C++ x86-64调用约定中的返回值 如果我编写一个返回void的函数,根据x86-64约定调用,我可以破坏rax/eax吗 关于返回double的函数的类似问题(因为实际返回将发生在xmm0中)

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,

如果我执行movq xmm0->rax。然后我得到一个数字,这个数字可以放在

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
    ,因此请确定您的要求

  • MOVQ允许您复制双精度
    的二进制表示形式。是的,当然,您可以在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乳胶源构建的。干杯,我不知道这些存在。