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

 

Мы переместили проверку STRLENGHT = 0 и комментарий //IF STRLENGHT > 0 также должен быть перемещен. После встраивания функции стало возможным избавиться от копирования ESI в этих строках.

mov  eax,esi

//*************

test eax,eax

jz  @Else1Begin

mov eax,[eax-$04]

Последние строки переписывают EAX и последнее использованное значение в EAX, которое было скопировано из ESI.

mov  eax,esi

//*************

//test eax,eax

test esi,esi

jz  @Else1Begin

//mov eax,[eax-$04]

mov eax,[esi-$04]

В действительности мы должны также посмотреть в точку возможного перехода Else1Begin и увидим, что значение из EAX также используется здесь. Мы видим, что значение в EAX сразу обнуляется в следующей за меткой строке и поэтому не используется. Так что первая строка кажется лишняя и должна быть удалена.

 

Code:

//mov  eax,esi

test esi,esi

jz  @Else1Begin

mov eax,[esi-$04]

 

function CharPos19(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 eax,[esi-$04]

mov edx,[esi-$04]

//mov  edx,eax

//I := 0;

xor eax,eax

//repeat

@RepeatBegin :

//Inc(I);

inc  eax

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

cmp  bl,[esi+eax-$01]

jz   @If2

cmp  edx,eax

jnl  @RepeatBegin

//if I <= StrLenght then

@If2 :

cmp  edx,eax

jnl  @Exit

//Result := I

//else

//Result := 0;

xor eax,eax

pop  esi

pop  ebx

ret

//else

//Result := 0;

@Else1Begin :

xor eax,eax

@Exit :

pop  esi

pop  ebx

end;

 

 

Как результат встраивания функции LStrLen мы можем также удалить одну инструкцию. Функция LStrLen возвращает свой результат в EAX, затем он копируется в EDX. MOV EAX, [ESI-$04]. Это можно изменить на MOV EDX, [ESI-$04], а инструкцию MOV EDX, EAX можно удалить.

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

Code:

function CharPos20(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 eax,eax

dec  esi

@RepeatBegin :

//Inc(I);

inc  eax

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

//cmp  bl,[esi+eax-$01]

cmp  bl,[esi+eax]

jz   @If2

cmp  edx,eax

jnl  @RepeatBegin

//if I <= StrLenght then

@If2 :

cmp  edx,eax

jnl  @Exit

//Result := 0;

xor eax,eax

pop  esi

pop  ebx

ret

//Result := 0;

@Else1Begin :

xor eax,eax

@Exit :

pop  esi

pop  ebx

end;

 

Когда мы проанализируем код, то мы увидим, что здесь есть смещение -1 при адресации строки. Нет необходимости вычитать это смещение при каждой итерации. Будет хорошо, если мы один раз уменьшим указатель на Str в ESI до начала цикла. Мы также можем уменьшить счетчик цикла в EAX, но затем мы должны будем увеличить его на единицу при возврате результата.

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

Code:

function CharPos22(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  eax,eax

xor ecx,ecx

dec  esi

@RepeatBegin :

//Inc(I);

//inc  eax

inc  ecx

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

//cmp  bl,[esi+eax]

cmp  bl,[esi+ecx]

jz   @If2

//cmp  edx,eax

cmp  edx,ecx

jnl  @RepeatBegin

//if I <= StrLenght then

@If2 :

//cmp  edx,eax

cmp  edx,ecx

jnl  @Exit

//Result := 0;

xor eax,eax

pop  esi

pop  ebx

ret

//Result := 0;

@Else1Begin :

xor eax,eax

pop  esi      //New

pop  ebx      //New

ret           //New

@Exit :

mov  eax, ecx

pop  esi

pop  ebx

end;

 

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

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

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

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


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