//这个是判断STr1是否包含STR2的一个函数
//该函数是DELPHI所写,我一个字母都没改
//只是我很多代码都读不懂,以致无法注释(无法理解整个函数的流程)
function _StrPos(const Str1, Str2: PChar): PChar; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX //保存现场
OR EAX,EAX
//如果 eax=0 则JMP @@2(也就是退出)
JE @@2
OR EDX,EDX
//如果 eax=0 则JMP @@2(也就是退出)
JE @@2
MOV EBX,EAX //首先保存EAX也就是STR1
MOV EDI,EDX //edi=str2
XOR AL,AL //al=0
MOV ECX,0FFFFFFFFH //ecx=一个足够大的缓冲长度
REPNE SCASB //如果不相等,则继续扫描 ,每一次扫描,ECX是要递减1的
//这也是计算STR2的长度的一个依据
NOT ECX //这里通过MOV ECX,FFFFFFFF 和NOT ECX
//就可以计算出STR2的长度,这是一个技巧
DEC ECX //多扫描一次,所以要减1才是STR2的真正长度
JE @@2 //如果ecx=0 then 则JMP @@2(也就是退出)
MOV ESI,ECX //ESI=ECX 也就是STR2的长度
MOV EDI,EBX //这里保存的是edi=STR1
MOV ECX,0FFFFFFFFH // ...
REPNE SCASB // ...
NOT ECX //同样方法,计算出STR1的长度
SUB ECX,ESI //执行ECX=ECX-ESI
JBE @@2 //如果小于0则退出,也就是说STR1长度小于STR2长度,则退出
//以下才是真正的比较开始,上面只是进行一些开场白而已
MOV EDI,EBX //源字符串=STR1=edi
LEA EBX,[ESI-1] //ebx=STR2的长度
@@1: MOV ESI,EDX //ESI指向STR2
LODSB //取一个字节
REPNE SCASB //如果不相等,则继续扫描
JNE @@2 //如果不等则退出,表示没扫到
MOV EAX,ECX //eax=ecx
PUSH EDI //保存EDI
MOV ECX,EBX //ECX=EBX
REPE CMPSB //相等则继续扫描
POP EDI //恢复EDI
MOV ECX,EAX //ECX=EAX
JNE @@1 //如果不等,则跳@@1
LEA EAX,[EDI-1] //eax(函数返回值)=edi-1
JMP @@3 //比较成功,退出
@@2: XOR EAX,EAX
@@3: POP EBX //恢复现场
POP ESI
POP EDI
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if _strpos('abcd','ab')<>nil then showmessage('找到了');
end;
[课程]FART 脱壳王!加量不加价!FART作者讲授!