C++ x86-64调用约定中的返回值 如果我编写一个返回void的函数,根据x86-64约定调用,我可以破坏rax/eax吗 关于返回double的函数的类似问题(因为实际返回将发生在xmm0中)
如果我执行movq xmm0->rax。然后我得到一个数字,这个数字可以放在C++ x86-64调用约定中的返回值 如果我编写一个返回void的函数,根据x86-64约定调用,我可以破坏rax/eax吗 关于返回double的函数的类似问题(因为实际返回将发生在xmm0中),c++,linux,assembly,x86-64,abi,C++,Linux,Assembly,X86 64,Abi,如果我执行movq xmm0->rax。然后我得到一个数字,这个数字可以放在 union { int, double }; 通过int。然后当我通过double读取它时,我得到了预期的double。我的行为有哪些陷阱 rax是一个暂存寄存器,double在类SSE中,因此它在xmm0/xmm1中返回。这些记录在SysV ABI中。在将返回值放入xmm0之前,没有任何东西可以阻止您将其用作草稿。中有指向ABI文档的链接 要回答#3,我们需要查看您的代码。可能是C++中的ub,
union {
int,
double
};
通过int。然后当我通过double读取它时,我得到了预期的double。我的行为有哪些陷阱
rax
是一个暂存寄存器,double
在类SSE中,因此它在xmm0
/xmm1
中返回。这些记录在SysV ABI中。在将返回值放入xmm0
之前,没有任何东西可以阻止您将其用作草稿。中有指向ABI文档的链接
要回答#3,我们需要查看您的代码。可能是C++中的ub,或者可能是您的程序集错误。
void
函数可以在所有arg返回寄存器(RAX、RDX、XMM0等)中保留它们想要的任何内容void
意味着调用者不应该使用您留下的任何值做任何事情(当然,除了保留呼叫的寄存器,如RBX、RBP和RSP)voiddouble
,因此请确定您的要求的二进制表示形式。是的,当然,您可以在C99中使用union将64位整数输入回一个double
。但是在C++中,联合类型双关只作为GNU扩展。在asm中,这些都是可以随意复制的位
int
成员的联合在这方面是虚假的,因为在x86-64 SysV ABI中,它只有32位。您可能正在截断尾数的低位32位,因此您可能只对尾数低位都为零的小整数进行了测试
事实上,这听起来并不正确;它应该截断双精度的上半部分,因为x86的浮点字节顺序将包含符号位的字节存储在最高地址。因此,除非您使用asm中的64位存储将其存储到union中,否则它不应该起作用。第3部分中的问题是什么?您是否返回该类型的并集?x86-64中的
rax
64位和int
32位不是吗?您是如何将64位放入32位的?您是否阅读了有关适用于amd64的SysV ABI的文档?中的当前ABI链接。Lu的github页面上有链接,链接到的PDF是根据当前git版本的ABI乳胶源构建的。干杯,我不知道这些存在。