了解程序集列表输出中的GCC浮点常量 [英] Understanding GCC's floating point constants in assembly listing output

查看:62
本文介绍了了解程序集列表输出中的GCC浮点常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于好奇,我正在使用编译器资源管理器来查看一些简单的C ++代码的汇编输出./p>

考虑以下示例

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

组装输出

 主要:推送RBPmov rbp,rspmovsd xmm0,QWORD PTR .LC0 [rip]movsd QWORD PTR [rbp-8],xmm0mov eax,0流行音乐退回.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 .(有可能不是这种情况,但是所有现代主流体系结构都对整数和浮点数使用相同的字节序,无论大小是整数.浮点的Endianness .)

因此,当作为 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 .您可以放入位模式并查看十六进制值.

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?

解决方案

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.

这篇关于了解程序集列表输出中的GCC浮点常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆