Во всех строках, в которых 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; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!