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

 

Вызов функции LStrLen сделан с префиксом System, иначе компилятор не сможет распознать ее. LStrLen реализована в модуле System.

Секция VAR удалена, поскольку мы не ссылаемся ни к каким переменным по имени.

Code:

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

asm

push ebx

push esi

mov  esi,edx

mov  ebx,eax

//StrLenght := Length(Str);

mov  eax,esi

//call System.@LStrLen

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

test eax,eax

jz  @LStrLenExit

mov eax,[eax-$04]

@LStrLenExit :

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

mov  edx,eax

//if StrLenght > 0 then

test edx,edx

jle @Else1Begin

//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 inline. Сделаем это путем трассировки и копированием ее тела из окна CPU view. Она состоит из четырех строк.

Code:

test eax,eax

jz +$03

mov eax,[eax-$04]

ret

 

Если указатель, переданный через EAX, в функцию LStrLen имеет nil, то ничего не делается, а просто производится возврат из функции. Если же указатель действительный, то длина строки расположена, в 4 предшествующих строке байтах. Эти 4 байта возвращаются, через регистр EAX. Для превращения этой функции в inline функцию, мы заменим вызов этой функции этими четырьмя строками. Инструкция JZ передает управление на инструкцию RET. Взамен инструкции RET мы передадим управление на метку LStrLenExit. Инструкция RET осуществляет возврат из функции. Данная инструкция RET должна быть удалена, иначе она вернет управление в CharPos, это не то, что мы хотим. А вот так наша встроенная (inline) функция должна выглядеть.

Code:

test eax,eax

jz  @LStrLenExit

mov eax,[eax-$04]

@LStrLenExit :

 

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

asm

push ebx

push esi

mov  esi,edx

mov  ebx,eax

//StrLenght := Length(Str);

mov  eax,esi

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

test eax,eax

//jz  @LStrLenExit

jz  @Else1Begin

mov eax,[eax-$04]

//@LStrLenExit :

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

mov  edx,eax

//if StrLenght > 0 then

//test edx,edx

//jle @Else1Begin

//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;

 

 

Теперь мы видим, что Паскаль строка; IF STRLENGHT > 0 THEN, проверяет длину точно также, как первая строка во встроенной LStrLen. Проверка Str на nil вполне достаточно ;-). Вторая строка удалена и первая изменена, чтобы переход был на @Else1Begin вместо простого выхода из встроенной StrLen функции, если Str равен nil. Теперь нет надобности в метке LStrLenExit.

Code:

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

asm

push ebx

push esi

mov  esi,edx

mov  ebx,eax

//StrLenght := Length(Str);

//mov  eax,esi

//if StrLenght > 0 then

//test eax,eax

test esi,esi

jz  @Else1Begin

//mov eax,[eax-$04]

mov eax,[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;

 

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

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

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

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


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