字串比较函数 strcmp

//重点在于函数中需要手动push一些寄存器, 且以ebp为基址计算参数的地址. 

#include "stdafx.h"

 
 
__declspec(naked) int strcmpA(char *s1, char *s2)    //__declspec(naked) 不用编译器自动附带各种push ebp pop ebp等语句
{
__asm
{
push ebp        
mov ebp, esp
push edi
push esi
 
xor al, al
 
mov edi, dword ptr ss:[ebp+4+4]    //ebp 0~3 存放的是原ebp值, ebp 4~7 存放的是函数返回地址, ebp 8~11 存放的是第一个参数, ebp 12~15 存放的是第二个参数.  参看栈里的内容.
 
mov ecx, -1
repnz scasb    //循环计算ebp+4+4字串的长度
not ecx
mov edi, DWORD PTR ss:[ebp+4+4]
mov esi, DWORD PTR ss:[ebp+4+8]
repe cmpsb    //循环 逐字节比较两字串中的对应字符, 相等则继续循环比较, 不等则退出循环
xor eax, eax
xor edx, edx
mov al, byte PTR [edi-1]
mov dl, byte PTR [esi-1]
 
sub al, dl    //因为函数返回值默认存放在EAX中, 所以此处巧妙的运用sub比较两字串末尾字符的值, 将结果(>0, == 0, <0)放在eax中.  非常好!
 
pop esi
pop edi
mov esp, ebp
pop ebp
ret          //须用ret作为函数返回, 否则后面指令不可预知
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char *s1 = "123";
char *s2 = "1234";
int result = strcmpA(s1, s2);
if (result > 0)
{
printf("s1 > s2\n");
else if (result == 0)
{
printf("s1 == s2\n");
}
else
{
printf("s1 < s2\n");
}
 
return 0;
}

posted on 2014-10-18 09:59  大呵呵  阅读(292)  评论(0编辑  收藏  举报

导航