Содержание материала

 

 

поскольку мы особо не обращали внимания при конвертировании на другие вещи, то у нас образовалось много строк типа MOV EAX, EAX. Сразу видно они излишни ;-). Просто удалим их.

Code:

function ForLoopBASM9(Start, Stop : Integer) : Integer;

asm

push ebp

push ebx

mov ebp,esp

add esp,-$14

//mov edx,edx

mov [ebp-$04],eax

//Result := 0;

xor eax,eax

mov [ebp-$0c],eax

//for I := Start to Stop do

mov eax,[ebp-$04]

//mov edx,edx

mov ecx,eax

mov eax, [ebp-$0c]               

  //begin

  @LoopStart :

    mov ebx, ecx

    //mov edx, edx

    cmp ebx, edx

    ja  @LoopEnd

    //Result := Result + I;

    //mov ecx,ecx

    add eax,ecx

    inc ecx

  //end;

  jmp @LoopStart

@LoopEnd :

  //mov eax,eax

mov esp,ebp

pop ebx

pop ebp

end;

 

При оптимизации ассемблерного кода есть две линии поведения, которым мы можем следовать. Мы можем думать как человек, пытаясь проявлять сообразительность, используя информацию из кода. Мы поступили так, когда распределяли регистры. Другой путь это пытаться использовать системный подход, так как поступает компилятор/оптимизатор. Это путь разработки алгоритмов. Данный подход позже даст многое для оптимизации, так мы поступали много раз выше. Удаление лишних строк кода, MOV EAX, EAX, был примером удаления мертвого кода, что является базисом для любых оптимизаторов.

Вверху функции мы еще имеем некоторые ссылки на стек. Для их удаления мы должны разместить эти переменные также в регистрах. В данное время мы выберем регистры EDI и ESI, поскольку они ни где не используются. Используем ESI для [EBP-$04] и EDI для [EBP-$0C]. Поскольку регистры ESI и EDI должны быть сохранены, мы поместим их в стек и потом восстановим.

Code:

function ForLoopBASM10(Start, Stop : Integer) : Integer;

asm

push ebp

push ebx

push esi

push edi

mov ebp,esp

add esp,-$14

//mov [ebp-$04],eax

mov esi,eax

//Result := 0;

xor eax,eax

//mov [ebp-$0c],eax

mov edi,eax

//for I := Start to Stop do

//mov eax,[ebp-$04]

mov eax,esi

mov ecx,eax

//mov eax, [ebp-$0c]

mov eax, edi

  //begin

  @LoopStart :

    mov ebx, ecx

    cmp ebx, edx

    ja  @LoopEnd

    //Result := Result + I;

    add eax,ecx

    inc ecx

  //end;

  jmp @LoopStart

@LoopEnd :

mov esp,ebp

pop edi

pop esi

pop ebx

pop ebp

end;

 

 

Фрейм стека больше нигде не используется и поэтому нет нужды его настраивать, это также сохранит 4 инструкции. Затем заметим, что две строки

mov eax,esi

mov ecx,eax

могут быть заменены одной.

mov ecx, esi

Это пример упрощения копирования с дальнейшим удалением мертвого кода. Любые другие строки не используют значения в EAX далее следующей строки, которая копирует обратно в ECX. Фактически это сразу переписывается строкой MOV EAX, EDI. Поэтому мы можем заменить вторую строку, на строку MOV ECX, ESI и удалить первую, которая становится мертвым кодом.

Code:

function ForLoopBASM11(Start, Stop : Integer) : Integer;

asm

//push ebp

push ebx

push esi

push edi

//mov ebp,esp

//add esp,-$14

mov esi,eax

//Result := 0;

xor eax,eax

mov edi,eax

//for I := Start to Stop do

//mov eax,esi

//mov ecx,eax

mov ecx, esi

mov eax, edi

  //begin

@LoopStart :

//mov ebx, ecx

//cmp ebx, edx

cmp ecx, edx

ja  @LoopEnd

  //Result := Result + I;

add eax,ecx

inc ecx

  //end;

jmp @LoopStart

@LoopEnd :

//mov esp,ebp

pop edi

pop esi

pop ebx

//pop ebp

end;

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить