Assembly x64组件故障rbx对rcx
我试图在macos上使用x64程序集实现我的strcpy函数版本。 我遇到了一个我不理解的SEGV错误 这是我的汇编代码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
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