简体   繁体   English

了解汇编列表输出中的 GCC 浮点常量

[英]Understanding GCC's floating point constants in assembly listing output

Just out of curiosity, I'm using Compiler Explorer to see the assembly output of some simple C++ codes.出于好奇,我正在使用Compiler Explorer查看一些简单 C++ 代码的汇编输出。

Consider the following example考虑以下示例

int main(void){
    double x = -5.3;
}

Assembly output装配输出

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

I would like to understand how to use我想了解如何使用

.LC0:
        .long   858993459
        .long   -1072352461

to get back my -5.3 .取回我的-5.3

My uninformed guess is that I need to merge the bit patterns of the two 32 bit integers and to interpret it as the bit pattern of a double precision floating point number.我不知情的猜测是我需要合并两个 32 位整数的位模式并将其解释为双精度浮点数的位模式。 But how, exactly?但是,究竟如何? Must I interpret the pattern as an IEEE754 double precision?我必须将模式解释为 IEEE754 双精度吗? In what order?以什么顺序?

But how, exactly?但是,究竟如何? ... ...

Yes, this is an integer representation of the IEEE754 binary64 (aka double ) bit pattern.是的,这是IEEE754 binary64(又名double位模式的整数表示。 GCC always prints FP constant this way because they are sometimes the result of constant-propagation, not FP literals that appear in the source. GCC 总是以这种方式打印 FP 常量,因为它们有时是常量传播的结果,而不是出现在源代码中的 FP 文字。 (Also it avoids any dependence on FP rounding in the assembler.) (它还避免了对汇编器中 FP 舍入的任何依赖。)

gcc always uses decimal for integer constants in its asm output, which is pretty inconvenient for humans. gcc 在其 asm 输出中始终使用十进制表示整数常量,这对人类来说非常不方便。 ( On the Godbolt compiler explorer , use the mouseover tooltip to get hex for any number.) 在 Godbolt 编译器资源管理器上,使用鼠标悬停工具提示获取任意数字的十六进制。)

Clang's asm output is nicer, and includes a comment with the decimal value of the number: Clang 的 asm 输出更好,并且包含带有数字十进制值的注释:

    .quad   -4605718748921121997    # double -5.2999999999999998

In what order?以什么顺序?

x86's float endianness matches its integer endianness: both are little-endian . x86 的浮点字节序匹配它的整数字节序:两者都是 little-endian (It's possible for this not to be the case, but all the modern mainstream architectures use the same endianness for integer and float, either big or little. Floating point Endianness? . And Endianness for floating point .) (这可能不是这种情况,但所有现代主流架构都对整数和浮点数使用相同的字节序,无论大小。 浮点字节序?浮点字节序。)

So when loaded as a 64-bit IEEE-754 double , the low 32 bits in memory are the low 32 bits of the double .因此,当作为64 位 IEEE-754 double加载时,内存中的低 32 位是double的低 32 位。

As @MichaelPetch explains in comments, the first/low dword is 0x33333333 , and the second/high dword is 0xC0153333 .正如@MichaelPetch 在评论中解释的那样,第一个/低位双字是0x33333333 ,第二个/高位双字是0xC0153333 Thus the entire double has a bit-pattern of C015333333333333因此,整个double精度位模式为C015333333333333

For single-precision float, there's https://www.h-schmidt.net/FloatConverter/IEEE754.html .对于单精度浮点数,有https://www.h-schmidt.net/FloatConverter/IEEE754.html (It's pretty nice, it breaks down the bits into binary with checkboxes, as well as hex bit-pattern and decimal fraction. Great for learning about how FP exponent / significand works.) (非常好,它使用复选框将位分解为二进制,以及十六进制位模式和十进制小数。非常适合了解 FP 指数/有效数的工作原理。)

For double-precision as well, see https://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html .对于双精度,请参阅https://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html You can put in a bit-pattern and see the hex value.您可以输入位模式并查看十六进制值。

#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