我尝试使用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)=“ a”
  
  str2(0x7fff5fbffb20)=“ poney”
  
  ft_strcat(str1,str2):0x5fbffb30
  
  str1(0x7fff5fbffb30)=“ aponey”


我的指针地址的高32位似乎消失了。我无法解释原因。

我知道这不仅仅是一个printf问题,因为如果我尝试从ft_strcat返回中打印字符串而不是指针地址,则会出现段错误。

任何想法 ?

最佳答案

错误在这里:

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

关于c - 汇编:返回64位指针地址(nasm UNIX x64),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29359895/

10-11 15:21