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

 

Во всех строках, в которых EAX использовался как I, EAX изменен на ECX. Поскольку I это возвращаемое значение функции при нахождении позиции и возвращаться должно через EAX, мы должны скопировать ECX в EAX до перехода на метку @Exit. Это приводит нас к небольшой проблеме, поскольку переход Else1Begin также осуществляется сюда, и в этой ситуации мы скопируем значение из ECX в EAX, которое мы только что очистили. Это исправляется строками помеченными как «new».

Теперь мы готовы к удалению лишнего копирования EAX. Регистр EBX используется только в одной строке. Это строка CMP BL, [ESI+ECX], которую изменим на CMP AL, [ESI+ECX]. Затем удалим ненужное теперь MOV EBX, EAX. Это устранение лишнего копирования и удаление мертвого кода и мы можем приступить к наиболее важной части оптимизации.

Code:

function CharPos23(Chr : Char; const Str : AnsiString) : Cardinal;

asm

push ebx

push esi

mov  esi,edx

//mov  ebx,eax

//if StrLenght > 0 then

test esi,esi

jz  @Else1Begin

//StrLenght := Length(Str);

mov edx,[esi-$04]

//I := 0;

xor ecx,ecx

dec  esi

@RepeatBegin :

//Inc(I);

inc  ecx

//until((Str[I] = Chr) or (I > StrLenght));

//cmp  bl,[esi+ecx]

cmp  al,[esi+ecx]

jz   @If2

cmp  edx,ecx

jnl  @RepeatBegin

//if I <= StrLenght then

@If2 :

cmp  edx,ecx

jnl  @Exit

//Result := 0;

xor eax,eax

pop  esi

pop  ebx

ret

//Result := 0;

@Else1Begin :

xor eax,eax

pop  esi     

pop  ebx     

ret

@Exit :

mov  eax, ecx

pop  esi

pop  ebx

end;

 

 

Для удаления лишнего копирования EDX (хранит указатель на Str), мы должны освободиться от использования EDX в других местах. Он используется в StrLenght, и мы разместим его в EBX вместо EDX.

Code:

function CharPos24(Chr : Char; const Str : AnsiString) : Cardinal;

asm

push ebx

push esi

mov  esi,edx

//if StrLenght > 0 then

test esi,esi

jz  @Else1Begin

//StrLenght := Length(Str);

//mov edx,[esi-$04]

mov ebx,[esi-$04]

//I := 0;

xor ecx,ecx

dec  esi

@RepeatBegin :

//Inc(I);

inc  ecx

//until((Str[I] = Chr) or (I > StrLenght));

cmp  al,[esi+ecx]

jz   @If2

//cmp  edx,ecx

cmp  ebx,ecx

jnl  @RepeatBegin

//if I <= StrLenght then

@If2 :

//cmp  edx,ecx

cmp  ebx,ecx

jnl  @Exit

//Result := 0;

xor eax,eax

pop  esi

pop  ebx

ret

//Result := 0;

@Else1Begin :

xor eax,eax

pop  esi     

pop  ebx     

ret

@Exit :

mov  eax, ecx

pop  esi

pop  ebx

end;

 

После этого лишнее копирование EDX и MOV ESI, EDX становятся лишними.

Code:

function CharPos25(Chr : Char; const Str : AnsiString) : Cardinal;

asm

push ebx

push esi

//mov  esi,edx

//if StrLenght > 0 then

//test esi,esi

test edx,edx

jz  @Else1Begin

//StrLenght := Length(Str);

//mov ebx,[esi-$04]

mov ebx,[edx-$04]

//I := 0;

xor ecx,ecx

//dec  esi

dec  edx

@RepeatBegin :

//Inc(I);

inc  ecx

//until((Str[I] = Chr) or (I > StrLenght));

//cmp  al,[esi+ecx]

cmp  al,[edx+ecx]

jz   @If2

cmp  ebx,ecx

jnl  @RepeatBegin

//if I <= StrLenght then

@If2 :

cmp  ebx,ecx

jnl  @Exit

//Result := 0;

xor eax,eax

pop  esi

pop  ebx

ret

//Result := 0;

@Else1Begin :

xor eax,eax

pop  esi     

pop  ebx     

ret

@Exit :

mov  eax, ecx

pop  esi

pop  ebx

end;

 

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

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

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

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


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