memcmp函数及其汇编实现

头文件:#include <string.h>

定义函数:int memcmp (const void *s1, const void *s2, size_t n);

函数说明:memcmp()用来比较s1 和s2 所指的内存区间前n 个字符。

字符串大小的比较是以ASCII 码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1 第一个字符值减去s2 第一个字符的值,若差为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如,字符串"Ac"和"ba"比较则会返回字符'A'(65)和'b'(98)的差值(-33)。

返回值:若参数s1 和s2 所指的内存内容都完全相同则返回0 值。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。

例: 
#include <string.h>
main(){
char *a = "aBcDeF";
char *b = "AbCdEf";
char *c = "aacdef";
char *d = "aBcDeF";
printf("memcmp(a, b):%d\n", memcmp((void*)a, (void*)b, 6));
printf("memcmp(a, c):%d\n", memcmp((void*)a, (void*)c, 6));
printf("memcmp(a, d):%d\n", memcmp((void*)a, (void*)d, 6));
}

执行结果:
memcmp(a, b):1 //字符串a>字符串b, 返回1
memcmp(a, c):-1 // 字符串a<字符串c, 返回-1
memcmp(a, d):0 //字符串a=字符串d, 返回0

 

汇编实现:

.386
.MODEL FLAT,C

.DATA

.CODE

EXmemcmp PROC

mov eax, [esp+0Ch]
test eax, eax ;未传入参数则退出
jz short retnull ;retn
mov edx, [esp+4]
push esi
push edi
mov esi, edx
mov edi, [esp+8+8]
or edx, edi
and edx, 3
jz short dwords_0
test eax, 1
jz short main_loop_0
mov cl, [esi]
cmp cl, [edi]
jnz short not_equal
inc esi
inc edi
dec eax
jz short done

main_loop_0:
mov cl, [esi]
mov dl, [edi]
cmp cl, dl
jnz short not_equal
mov cl, [esi+1]
mov dl, [edi+1]
cmp cl, dl
jnz short not_equal
add edi, 2
add esi, 2
sub eax, 2
jnz short main_loop_0

done: 
pop edi
pop esi

retnull:
retn
; ---------------------------------------------------------------------------

dwords_0: 
mov ecx, eax
and eax, 3
shr ecx, 2
jz short tail_loop_start
repe cmpsd
jz short tail_loop_start
mov ecx, [esi-4]
mov edx, [edi-4]
cmp cl, dl
jnz short difference_in_tail
cmp ch, dh
jnz short difference_in_tail
shr ecx, 10h
shr edx, 10h
cmp cl, dl
jnz short difference_in_tail
cmp ch, dh

difference_in_tail:
mov eax, 0

not_equal: 
sbb eax, eax
pop edi
sbb eax, 0FFFFFFFFh
pop esi
retn
; ---------------------------------------------------------------------------

tail_loop_start: 
test eax, eax
jz short done
mov edx, [esi]
mov ecx, [edi]
cmp dl, cl
jnz short difference_in_tail
dec eax
jz short tail_done
cmp dh, ch
jnz short difference_in_tail
dec eax
jz short tail_done
and ecx, 0FF0000h
and edx, 0FF0000h
cmp edx, ecx
jnz short difference_in_tail
dec eax

tail_done:
pop esi
retn

ret
EXmemcmp ENDP

END

posted @ 2018-08-02 16:50  _ymzh  阅读(1544)  评论(0编辑  收藏  举报