程序集:返回 64 位指针地址(nasm unix x64)
Assembly : Returning 64 bits pointer address (nasm unix x64)
我尝试使用 asm 重现 strcat 标准 c 函数。
这是我的 C 测试主要内容:
char *ft_strcat(char *s1, const char *s2);
int main(void)
{
char str1[60];
str1[0] = 'a';
str1[1] = '[=11=]';
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) = "a"
str2 (0x7fff5fbffb20) = "poney"
ft_strcat(str1, str2) : 0x5fbffb30
str1 (0x7fff5fbffb30) = "aponey"
我的指针地址的高32位好像不见了。我无法解释为什么。
我知道这不仅仅是一个 printf 问题,因为如果我尝试从 ft_strcat return 打印字符串而不是指针地址,我会得到一个段错误。
有什么想法吗?
错误在这里:
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
不好意思,这不是 asm 问题。我通过在 main.
顶部添加 #include "libfts.h" 解决了这个问题
如果没有函数原型,我想程序无法判断函数返回的是 1 字节还是 8 字节..
在这一行:
mov rax, qword rdi
不需要 qword,因为移动 from/to 64 位寄存器已经复制了 8 个字节
我还在 Makefile 中添加了编译器标志以防止此类错误。
我尝试使用 asm 重现 strcat 标准 c 函数。
这是我的 C 测试主要内容:
char *ft_strcat(char *s1, const char *s2);
int main(void)
{
char str1[60];
str1[0] = 'a';
str1[1] = '[=11=]';
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) = "a"
str2 (0x7fff5fbffb20) = "poney"
ft_strcat(str1, str2) : 0x5fbffb30
str1 (0x7fff5fbffb30) = "aponey"
我的指针地址的高32位好像不见了。我无法解释为什么。
我知道这不仅仅是一个 printf 问题,因为如果我尝试从 ft_strcat return 打印字符串而不是指针地址,我会得到一个段错误。
有什么想法吗?
错误在这里:
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
不好意思,这不是 asm 问题。我通过在 main.
顶部添加 #include "libfts.h" 解决了这个问题如果没有函数原型,我想程序无法判断函数返回的是 1 字节还是 8 字节..
在这一行:
mov rax, qword rdi
不需要 qword,因为移动 from/to 64 位寄存器已经复制了 8 个字节
我还在 Makefile 中添加了编译器标志以防止此类错误。