如果我做movq xmm0 - > RAX。然后我得到一个可以放到
的号码union {
int,
double
};
通过int。然后,当我通过双读它时,我得到预期的双倍。我的行为有哪些陷阱?
答案 0 :(得分:2)
rax
是一个临时注册,double
位于SSE类中,因此会在xmm0
/ xmm1
中返回。这些记录在SysV ABI中。在将返回值放入之前,没有什么可以阻止您使用xmm0
作为临时。 x86 tag wiki中有ABI文档的链接。
要回答#3,我们需要查看您的代码。也许它是C ++中的UB,或者你的程序集是错误的。
答案 1 :(得分:0)
是的,void
函数可以在所有arg返回寄存器(RAX,RDX,XMM0等)中留下他们想要的内容。 void
表示调用者不应该对你留在任何地方的任何值做任何事情(当然除了RBX,RBP和RSP之类的调用保留寄存器)。
类似于什么?一个函数不能被声明为返回void double
,所以IDK就是你所要求的。
MOVQ允许您复制double
的二进制表示。是的,当然你可以使用C99中的union将64位整数输回到double
。但是在C ++中,union type-punning只作为GNU扩展而合法。在asm中,它只是你可以随意复制的所有内容。
请注意,与int
成员的联合是伪造的,因为x86-64 SysV ABI中只有32位。你可能会截断你的尾数的低32位,所以你可能只测试了尾数的低位全为零的小整数。
实际上,这听起来并不合适;它应该截断double
的高一半,因为x86的浮点字节顺序存储包含最高地址的符号位的字节。所以除非你在asm中使用64位存储存储到联合中,否则它不应该工作。