[英]Understanding GCC's floating point constants in assembly listing output
出於好奇,我正在使用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(又名double
)位模式的整數表示。 GCC 總是以這種方式打印 FP 常量,因為它們有時是常量傳播的結果,而不是出現在源代碼中的 FP 文字。 (它還避免了對匯編器中 FP 舍入的任何依賴。)
gcc 在其 asm 輸出中始終使用十進制表示整數常量,這對人類來說非常不方便。 ( 在 Godbolt 編譯器資源管理器上,使用鼠標懸停工具提示獲取任意數字的十六進制。)
Clang 的 asm 輸出更好,並且包含帶有數字十進制值的注釋:
.quad -4605718748921121997 # double -5.2999999999999998
以什么順序?
x86 的浮點字節序匹配它的整數字節序:兩者都是 little-endian 。 (這可能不是這種情況,但所有現代主流架構都對整數和浮點數使用相同的字節序,無論大小。 浮點字節序?和浮點字節序。)
因此,當作為64 位 IEEE-754 double
加載時,內存中的低 32 位是double
的低 32 位。
正如@MichaelPetch 在評論中解釋的那樣,第一個/低位雙字是0x33333333
,第二個/高位雙字是0xC0153333
。 因此,整個double
精度位模式為C015333333333333
對於單精度浮點數,有https://www.h-schmidt.net/FloatConverter/IEEE754.html 。 (非常好,它使用復選框將位分解為二進制,以及十六進制位模式和十進制小數。非常適合了解 FP 指數/有效數的工作原理。)
對於雙精度,請參閱https://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html 。 您可以輸入位模式並查看十六進制值。
#include <iostream>
typedef struct{
union{
double decimal;
struct{
int a;
int b;
}v;
};
}Double2Int_t;
int main(){
int a1=858993459;
int a2=-1072352461;
double value=-5.3;
Double2Int_t decimal;
decimal.decimal=value;
std::cout<<decimal.v.a<<" "
<<decimal.v.b<<std::endl;
Double2Int_t decimal2;
decimal2.v.a=a1;
decimal2.v.b=a2;
std::cout<<decimal2.decimal<<std::endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.