Understanding GCC's floating point constants in assembly listing output

陌路散爱 提交于 2021-02-16 13:45:08

问题


Just out of curiosity, I'm using Compiler Explorer to see the assembly output of some simple C++ codes.

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.

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. But how, exactly? Must I interpret the pattern as an IEEE754 double precision? In what order?


回答1:


But how, exactly? ...

Yes, this is an integer representation of the IEEE754 binary64 (aka double) bit pattern. GCC always prints FP constant this way because they are sometimes the result of constant-propagation, not FP literals that appear in the source. (Also it avoids any dependence on FP rounding in the assembler.)

gcc always uses decimal for integer constants in its asm output, which is pretty inconvenient for humans. (On the Godbolt compiler explorer, use the mouseover tooltip to get hex for any number.)

Clang's asm output is nicer, and includes a comment with the decimal value of the number:

    .quad   -4605718748921121997    # double -5.2999999999999998

In what order?

x86's float endianness matches its integer endianness: both are 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.

As @MichaelPetch explains in comments, the first/low dword is 0x33333333, and the second/high dword is 0xC0153333. Thus the entire double has a bit-pattern of C015333333333333

For single-precision float, there's 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.)

For double-precision as well, see https://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html. You can put in a bit-pattern and see the hex value.



来源:https://stackoverflow.com/questions/51883374/understanding-gccs-floating-point-constants-in-assembly-listing-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!