要求写一个比较高效的文件比较程序,竟然发现memcmp比strcmp要快很多,于是跟踪调试,发现它们的实现原理:
intel/strcmp.asm:
mov edx, dword ptr [esp + 4] ;取第二个参数地址
mov ecx, dword ptr [esp + 8] ;取第一个参数地址
test edx, 3 ;edx是第二个参数的地址,这里即检验该地址是否是4的倍数。
;因为如果edx&3!=0,则其最低两位不为1,所以为4的倍数。这里有个内存地址对齐的问题。
jne dopartial ;如果地址不是4的倍数,就跳到dopartial去处理。
dodwords:
mov eax, dword ptr [edx]
cmp al, byte ptr [ecx]
jne donene
or al, al ;看看字符串是否结束,这就是strcmp之所以比memcmp慢的地方了。
je doneeq ;如果 al==0,则比较结束
cmp ah, byte ptr [ecx + 1]
jne donene
or ah, ah
je doneeq
shr eax, 10h ;右移16位
cmp al, byte ptr [ecx + 2]
jne donene
or al, al
je doneeq
cmp ah, byte ptr [ecx + 3]
jne donene
or ah, ah
je doneeq
add ecx, 4
add edx, 4
or ah, ah
jne dodwords
move edi, edi ;这里一直大惑不解,不明白为什么这里要多出这两个字节来
doneeq:
xor eax, eax ÿ
intel/strcmp.asm:
mov edx, dword ptr [esp + 4] ;取第二个参数地址
mov ecx, dword ptr [esp + 8] ;取第一个参数地址
test edx, 3 ;edx是第二个参数的地址,这里即检验该地址是否是4的倍数。
;因为如果edx&3!=0,则其最低两位不为1,所以为4的倍数。这里有个内存地址对齐的问题。
jne dopartial ;如果地址不是4的倍数,就跳到dopartial去处理。
dodwords:
mov eax, dword ptr [edx]
cmp al, byte ptr [ecx]
jne donene
or al, al ;看看字符串是否结束,这就是strcmp之所以比memcmp慢的地方了。
je doneeq ;如果 al==0,则比较结束
cmp ah, byte ptr [ecx + 1]
jne donene
or ah, ah
je doneeq
shr eax, 10h ;右移16位
cmp al, byte ptr [ecx + 2]
jne donene
or al, al
je doneeq
cmp ah, byte ptr [ecx + 3]
jne donene
or ah, ah
je doneeq
add ecx, 4
add edx, 4
or ah, ah
jne dodwords
move edi, edi ;这里一直大惑不解,不明白为什么这里要多出这两个字节来
doneeq:
xor eax, eax ÿ