簡體   English   中英

了解匯編列表輸出中的 GCC 浮點常量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM