出于好奇,我使用Compiler Explorer来查看一些简单C++代码的汇编输出。
考虑以下example
int main(void){
double x = -5.3;
}
汇编输出
main:
push rbp
mov rbp, rsp
movsd xmm0, QWORD PTR .LC0[rip]
movsd QWORD PTR [rbp-8], xmm0
mov eax, 0
pop rbp
ret
.LC0:
.long 858993459
.long -1072352461
我想了解如何使用
.LC0:
.long 858993459
.long -1072352461
我的-5.3
我不知情的猜测是,我需要合并两个32位整数的位模式,并将其解释为双精度浮点数的位模式。但是,确切地说,如何?我必须将模式解释为IEEE754双精度?以什么顺序?
2条答案
按热度按时间kulphzqa1#
但是,具体是怎么做的呢?......
是的,这是IEEE754 binary64 (aka
double
)位模式的整数表示。GCC总是以这种方式打印FP常量,因为它们有时是常量传播的结果,而不是出现在源代码中的FP文字。(此外,它避免了对汇编程序中FP舍入的任何依赖。)gcc在其asm输出中总是使用decimal作为整数常量,这对人类来说非常不方便。(在Godbolt编译器资源管理器上,使用鼠标悬停工具提示可以获得任何数字的十六进制。)
Clang的asm输出更好,包括一个带有数字十进制值的注解:
按什么顺序?
x86的float endianness与其integer endianness匹配:两者都是little-endian。(也有可能不是这种情况,但所有现代主流体系结构都对整数和浮点数使用相同的endian,无论是大的还是小的。Floating point Endianness?。还有Endianness for floating point。)
因此,当作为64-bit IEEE-754
double
加载时,内存中的低32位是double
的低32位。正如@MichaelPetch在评论中解释的那样,第一个/低dword是
0x33333333
,第二个/高dword是0xC0153333
。因此整个double
具有C015333333333333
的位模式对于单精度浮点数,有https://www.h-schmidt.net/FloatConverter/IEEE754.html。(它非常好,它用复选框将位分解为二进制,以及十六进制位模式和十进制小数。非常适合学习FP指数/有效数的工作原理。)
对于双精度,请参阅https://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html。您可以输入位模式并查看十六进制值。
ajsxfq5m2#