汇编:返回64位指针地址(nasm unix x64)

时间:2015-03-31 03:03:53

标签: c pointers assembly 64-bit nasm

我尝试使用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返回打印字符串而不是指针地址,我会得到一个段错误。

有什么想法吗?

2 个答案:

答案 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

另外我认为主循环应该像这样重写(不是最佳的,因为它一次只有一个字符,但考虑到你在每个循环中增加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

答案 1 :(得分:0)

好吧,我的坏,这不是一个问题。我通过添加#include&#34; libfts.h&#34;解决了这个问题。在我的主要顶部。

如果没有函数原型,我认为程序无法判断函数是返回1还是8字节。

在这一行:

mov rax,qword rdi

不需要qword,因为从/到64位寄存器的移动已经复制了8个字节

我还在Makefile中添加了compilator标志,以防止出现这种错误。