在 x86 程序集中将 float 文字转换为 int 表示?

Convert a float literal to int representation in x86 assembly?

以下C代码:

int main()
{
    float f;
    f = 3.0;
}

转换为以下汇编指令:

main:
  pushl %ebp
  movl %esp, %ebp
  subl , %esp
  flds .LC0
  fstps -4(%ebp)
  movl [=11=], %eax
  leave
  ret
.LC0:
  .long 1077936128

计算 float 文字的 .long/int 表示的正确方法是什么?

例如 10779361283.0 生成上面的示例


For this example gcc is used with the -m32 -S -O0 -fno-stack-protector -fno-asynchronous-unwind-tables flags using intel settings to generate the assembly output.

参考文献:

Compiler Explorer Link 带有编译标志和其他设置

x86 FPU 硬件使用 IEEE754 binary32 / binary64 表示 float / double.

确定浮点数的 IEEE 754 表示形式对人类来说并非易事。在手写的汇编代码中,通常最好使用 .float.double 指令来代替:

.float 3.0    # generates 3.0 as a 32 bit float
.double 3.0   # generates 3.0 as a 64 bit float

如果您真的想手动计算,请参阅explanations on Wikipedia。作为练习这样做可能很有趣,但对于实际编程来说,这很乏味而且几乎没有用。

编译器在内部进行转换(四舍五入到最接近的可表示 FP 值),因为 FP 值通常不是直接来自源代码中的文字;它们可以来自不断的折叠。例如1.23 * 4.56 在编译时进行评估,因此编译器已经以 float 或 double 二进制表示形式的 FP 值结束。将它们打印回十进制以便汇编器解析并重新转换为二进制会比较慢,并且可能需要很多小数位。


要计算 32 位浮点数作为 32 位整数的表示,您可以使用 an online IEEE754 converter,或像这样的程序:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char *argv[])
{
    union { uint32_t u32; float f32; } intfloat;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s some-number\n", argv[0]);
        return EXIT_FAILURE;
    }

    intfloat.f32 = atof(argv[1]);

    printf("0x%08" PRIx32 "\n", intfloat.u32);

    return EXIT_SUCCESS;
}