程序集:返回 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

另外我认为主循环应该像这样重写(不是最优的,因为它一次一个字符,但考虑到你在每个循环中递增 rsirdi 一次,我认为这是你打算做的):

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 中添加了编译器标志以防止此类错误。