我尝试使用asm重现strcat标准c函数。
这是我的C测试主要内容:
char *ft_strcat(char *s1, const char *s2);
int main(void)
{
char str1[60];
str1[0] = 'a';
str1[1] = '\0';
char str2[] = "poney";
printf("\n>> Test de ft_strcat <<\n\n");
printf("str1 (%p) = \"%s\"\n", str1, str1);
printf("str2 (%p) = \"%s\"\n", str2, str2);
printf("ft_strcat(str1, str2) : %p\n", ft_strcat(str1, str2));
printf("str1 (%p) = \"%s\"\n", str1, str1);
return (0);
}
和我的汇编代码
section .text
global _ft_strcat
_ft_strcat:
mov rax, qword rdi ; save pointer address in rdi to return it later
start:
cmp [rdi], byte 0
jz next
inc rdi
jmp start
next:
cmp [rsi], byte 0
je end
mov r11, [rsi]
mov [rdi], r11
inc rdi
inc rsi
jmp next
end:
mov [rdi], byte 0
ret ; return rax
结果如下:
str1(0x7fff5fbffb30)=&#34; a&#34;
str2(0x7fff5fbffb20)=&#34; poney&#34;
ft_strcat(str1,str2):0x5fbffb30
str1(0x7fff5fbffb30)=&#34; aponey&#34;
看来我指针地址的高32位已经消失了。我无法解释原因。
我知道这不仅仅是一个printf问题,因为如果我尝试从ft_strcat返回打印字符串而不是指针地址,我会得到一个段错误。
有什么想法吗?
答案 0 :(得分:0)
错误在于:
mov rax, qword rdi ; save pointer address in rdi to return it later
我认为这应该是:
mov rax,rdi ; save pointer address in rdi to return it later
另外我认为主循环应该像这样重写(不是最佳的,因为它一次只有一个字符,但考虑到你在每个循环中增加rsi
和rdi
一次,我认为这就是你打算做的事情):
next:
cmp byte [rsi],0
je end
mov cl,[rsi] ;load 8 bits
mov [rdi],cl ;store 8 bits
inc rdi
inc rsi
jmp next
答案 1 :(得分:0)
好吧,我的坏,这不是一个问题。我通过添加#include&#34; libfts.h&#34;解决了这个问题。在我的主要顶部。
如果没有函数原型,我认为程序无法判断函数是返回1还是8字节。
在这一行:
mov rax,qword rdi
不需要qword,因为从/到64位寄存器的移动已经复制了8个字节
我还在Makefile中添加了compilator标志,以防止出现这种错误。