【发布时间】:2020-07-27 06:48:51
【问题描述】:
我正在尝试在 asm 中实现我自己的 strcmp。这是 ft_strcmp.s 文件:
global ft_strcmp
section .text
ft_strcmp:
mov eax, [rdi]
sub eax, [rsi]
jne .exit
cmp byte [rdi], 0 ; if s1 end
je .exit
cmp byte [rsi], 0 ; if s2 end
je .exit
inc rdi
inc rsi
jmp ft_strcmp
.exit:
ret
第一个字母没问题: char *s1 = "你好世界" char *s2 = "Jdllo 世界" 结果是 1。 (0000 0001)
问题是当我尝试比较这些字符串时:
char *s1 = "Hello World"
char *s2 = "Hdllo 世界"
RAX 中的结果不是 1,而是 256。(0000 0001 0000 0000)
另一个例子:
char *s1 = "Hello World"
char *s2 = "Hcllo 世界"
RAX 中的结果不是 2,而是 512。(0000 0010 0000 0000)
正如您已经理解的那样,第三个不同字母的结果将是:
char *s1 = "Hello World"
char *s2 = "Heklo 世界"
RAX 中的结果不是 1,而是 65 536。(0000 0001 0000 0000 0000 0000)
我意识到 RAX 递增不正确,但我在代码中找不到错误。 所以我请你帮助我理解。
【问题讨论】:
-
您正在使用
eax从内存中加载和减去 32 位值。除了您看到的结果外,您还有可能超过 nul 终止字符。幸运的是,字符串长度加上 nul 终止符是(4)的倍数,并且尚未使用'Hello Worle'完成测试。使用al-eax的最低有效字节 - 解决了这个问题,但随后需要 符号扩展al到完整的 64 位rax返回值。 -
我最后一句话错了。假设返回值为 32 位
'int',则只需对 32 位eax值进行符号扩展即可。
标签: assembly x86-64 nasm strcmp