- 如果我编写一个返回 void 的函数,根据 x86-64 约定调用,我可以破坏 rax/eax 吗?
- 关于返回双精度的函数的类似问题(因为实际返回将发生在 xmm0 中)
-
如果我做 movq xmm0 -> rax。然后我得到一个可以放入的数字
union { int, double };
通过 int。然后当我通读双倍时,我得到了预期的双倍。我的行为有哪些陷阱?
rax
是一个暂存寄存器,double
在类 SSE 中,因此它以xmm0
/xmm1
返回。这些都记录在 SysV ABI 中。没有什么可以阻止您在将返回值放置之前将xmm0
用作临时。在 x86 标签 wiki 中有指向 ABI 文档的链接。
要回答#3,我们需要查看您的代码。也许是 UB 在C++,或者您的程序集是错误的。
-
是的,
void
函数可以在所有arg返回寄存器(RAX,RDX,XMM0等)中保留任何它们想要的内容。void
意味着调用方不应该对你留在任何地方的任何值做任何事情(当然,除了调用保留的寄存器,如RBX、RBP和RSP)。 -
类似于什么? 函数不能声明为返回
void double
,所以IDK你在问什么。 -
MOVQ 允许您复制
double
的二进制表示形式。 是的,当然,您可以将该 64 位整数键入双关语,并在 C99 中输入并集的double
。 但在C++,联合类型双关只作为GNU扩展是合法的。 在asm中,它只是您可以随心所欲地复制的位。
请注意,具有int
成员的联合是伪造的,因为这在 x86-64 SysV ABI 中只有 32 位。 您可能正在截断尾数的低 32 位,因此您可能只对尾数的低位都为零的小整数进行了测试。
实际上,这听起来不对;它应该截断double
的高半部分,因为x86的浮点字节顺序在最高地址存储包含符号位的字节。因此,除非您使用 asm 中的 64 位存储存储在联合中,否则它应该不起作用。