Assembly x64组件故障rbx对rcx

Assembly x64组件故障rbx对rcx,assembly,x86-64,cpu-registers,calling-convention,abi,Assembly,X86 64,Cpu Registers,Calling Convention,Abi,我试图在macos上使用x64程序集实现我的strcpy函数版本。 我遇到了一个我不理解的SEGV错误 这是我的汇编代码 section .text global _ft_strcpy _ft_strcpy: mov rax, rdi loop: mov rbx, [rsi] mov [rdi], rbx inc rdi inc rsi cmp [rsi] , byte 0 jne loop end: mov [rdi

我试图在macos上使用x64程序集实现我的strcpy函数版本。 我遇到了一个我不理解的SEGV错误

这是我的汇编代码

section .text
    global _ft_strcpy

_ft_strcpy:
    mov rax, rdi

loop:
    mov rbx, [rsi]
    mov [rdi], rbx
    inc rdi
    inc rsi
    cmp [rsi] , byte 0
    jne loop

end:
    mov [rdi], byte 0
    ret
这是我用来测试的主要.c

#include <stdio.h>
#include <string.h>

int main(void)
{
    char src [11] = "Hello moto";
    char dest [11];
    ft_strcpy(dest, src);

    printf("|%p|\n", src);
    printf("|%s|\n", src);
    printf("|%p|\n", dest);
    printf("|%s|\n", dest); 
    return (0);
}
segfault似乎发生在我调用ft_strcpy后的第一次printf调用中。 当我在汇编代码中使用rcx寄存器而不是rbx寄存器时,这个程序可以工作。 我已经查找了rcx和rbx Caller saved与Callee saved之间的区别,但是我不明白为什么会导致这个问题。我错过了什么

请随意指出任何不好的做法,我在这里接受任何建议

谢谢你的阅读

请随意指出任何不好的做法,我在这里接受任何建议


复制循环一次加载并存储8个字节,但以1字节的增量递增。

如果被调用方希望使用寄存器RBX、RBP和R12–R15,则必须在将控制返回给调用方之前恢复其原始值。哦。。。。。非常感谢。我可以问一下它来自什么资源吗?维基百科:Linux和MacOS都使用x86-64 System V ABI/调用约定。谢谢!我在想:访问寄存器的低位是否比访问整个寄存器的成本更低?对不起,如果不清楚的话,我是新来的。顺便说一句,如果你有汇编语言和机器语言之间的链接方面的任何资源,我就要了@我推荐阿格纳·福格。它包含有关指令编码的信息,具体取决于操作数大小等。复制8字节意味着源和目标中的缓冲区溢出7字节。@yorncl访问它们进行读取没有问题,但如果写入寄存器的低位8、中间8或低位16位,需要额外的µop将写入值与剩余位合并。写入低32位时不是这种情况,因为在这种情况下,高32位被调零。因此,当从RAM加载单个字节时,考虑使用MOVZX以获得更好的性能。在您的情况下,一次复制8个字节,直到剩下不到8个字节为止。然后,如果总大小允许,重复最后8个字节。如果您确实需要加载单个字节,请使用movzx来避免错误的依赖项和/或其他部分寄存器写入骗局。
=================================================================
==53615==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000097 (pc 0x0001087a2c5f bp 0x7ffee745d990 sp 0x7ffee745d880 T0)
==53615==The signal is caused by a READ memory access.
==53615==Hint: address points to the zero page.
    #0 0x1087a2c5e in main main.c:10
    #1 0x7fff796e33d4 in start (libdyld.dylib:x86_64+0x163d4)

==53615==Register values:
rax = 0x00007ffee745d8c0  rbx = 0x000000000000004f  rcx = 0x4f4d204f4c4c4500  rdx = 0x00001fffdce8bb10  
rdi = 0x00000001087a2e60  rsi = 0x00007ffee745d8aa  rbp = 0x00007ffee745d990  rsp = 0x00007ffee745d880  
 r8 = 0x00001fffdce8bb10   r9 = 0x00000001087a2e20  r10 = 0x0000000117f89c30  r11 = 0x00007ffddecbaa80  
r12 = 0x0000000000000000  r13 = 0x0000000000000000  r14 = 0x0000000000000000  r15 = 0x0000000000000000  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV main.c:10 in main