gcc - 了解汇编列表输出中的 GCC 浮点常量
问题描述
出于好奇,我正在使用Compiler Explorer查看一些简单 C++ 代码的汇编输出。
考虑以下示例
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 双精度吗?以什么顺序?
解决方案
但是,究竟如何?...
是的,这是IEEE754 binary64 (aka double
)位模式的整数表示。GCC 总是以这种方式打印 FP 常量,因为它们有时是常量传播的结果,而不是出现在源代码中的 FP 文字。(它还避免了对汇编器中 FP 舍入的任何依赖。)
gcc 在其 asm 输出中始终使用十进制表示整数常量,这对人类来说非常不方便。(在 Godbolt 编译器资源管理器上,使用鼠标悬停工具提示获取任意数字的十六进制。)
Clang 的 asm 输出更好,并且包含带有数字十进制值的注释:
.quad -4605718748921121997 # double -5.2999999999999998
以什么顺序?
x86 的浮点字节序匹配它的整数字节序:两者都是 little-endian。(情况可能并非如此,但所有现代主流架构都对整数和浮点数使用相同的字节序,无论大小。 浮点字节序?和浮点字节序。)
因此,当作为64 位 IEEE-754double
加载时,内存中的低 32 位是double
.
正如@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。您可以输入位模式并查看十六进制值。
推荐阅读
- python - 在无头模式下无法在 ChromeDrive 中打开网站
- c# - 使用 TreeView 控件的悬停菜单
- c# - 如何创建指向同一唯一字符串列的 2 个字符串外键?
- python-3.x - Python glob.glob 在 Mac 上返回空列表
- hibernate - 休眠获取两个时间戳之间的时间段
- machine-learning - ValueError: X.shape[1] = 772 应该等于 676,训练时的特征数
- pine-script - NR4 代码看到 Pine 脚本运行错误“内部服务器 pine 编译错误”
- github - 为什么我会收到不同的结果搜索存储库?
- html - 重定向到另一个页面到特定部分
- javascript - 如何从 props.map 中删除空值