我一直在 x86_64 程序集中编写自己的 strcmp 函数的简单实现。
我编写了一个 C 测试程序来将其行为与 C 库中的真实 strcmp 进行比较。
即使两个函数似乎返回相同的值,条件
(strcmp(s1,s2) == my_strcmp(s1,s2))
好像是假的。 my_strcmp(s1,s2) == strcmp(s1,s2)
似乎是真的。
我错过了什么?
在排除故障时,我用 C 语言的 strcmp 实现和相同的测试程序进行了编译,只是为了验证: 效果很好,所有行为都是预期的。
my_strcmp.s:
; Function: int my_strcmp(const char *dest, const char *src);
; Arguments:
; rdi s1
; rsi s2
; Variable:
; rcx counter
; Returned value :
section .text
global my_strcmp
my_strcmp:
; Function prologue (optional)
push rbp
mov rbp, rsp
xor rcx,rcx
loop:
mov al, byte [rdi]
mov bl, byte [rsi]
cmp al, bl
jne not_equal
test al,al
je null_byte_found
inc rdi
inc rsi
jmp loop
not_equal:
sub al, bl
movsx rax, al
jmp end
null_byte_found:
xor rax,rax
jmp end
end:
; Function epilogue (optional)
mov rsp, rbp
pop rbp
ret
main.c(测试程序):
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
extern int my_strcmp(const char *s1, const char *s2);
void test_my_strcmp();
int main() {
test_my_strcmp();
return 0;
}
void test_my_strcmp(){
char s1[10] = "123456789";
char s2[10] = "12345AAA";
int a = strcmp(s1,s2);
int b = my_strcmp(s1,s2);
if ( a == b)
printf("a == b\n");
if (strcmp(s1,s2) == -11)
printf("strcmp return value is -11\n");
if (-11 == my_strcmp(s1,s2))
printf("my_strcmp retun value is -11\n");
if (strcmp(s1,s2) == my_strcmp(s1,s2))
printf("OK1\n");
if (my_strcmp(s1,s2) == strcmp(s1,s2))
printf("OK2\n");
}
my_strcmp.c(只是为了验证):
int my_strcmp(const char *s1, const char *s2){
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
return (*s1 - *s2);
}
创建 3 个文件后
my_strcmp.s
、my_strcmp.c
和 main.c
、nasm -f elf64 -g my_strcmp.s -o my_strcmp_assembly.o
gcc -c my_strcmp.c
gcc main.c my_strcmp.o -o c_version.out
gcc main.c my_strcmp_assembly.o -o asm_version.out
./c_version.out && ./asm_version.out
a == b
strcmp return value is -11
ft_strcmp retun value is -11
OK1
OK2
a == b
strcmp return value is -11
ft_strcmp retun value is -11
OK2
gcc版本:11.4.0(最新) nasm 版本:2.15.05(最新)
``
您正在使用
%bl
作为临时寄存器。
%rbx
或使用其他寄存器。请参阅:https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf的第 3.2.1 节,了解寄存器列表以及调用者/被调用者如何使用它们