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

jan*_*iks 2 c floating-point x86 assembly ieee-754

以下C代码:

int main()
{
    float f;
    f = 3.0;
}
Run Code Online (Sandbox Code Playgroud)

转换为以下汇编指令:

main:
  pushl %ebp
  movl %esp, %ebp
  subl $16, %esp
  flds .LC0
  fstps -4(%ebp)
  movl $0, %eax
  leave
  ret
.LC0:
  .long 1077936128
Run Code Online (Sandbox Code Playgroud)

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

例如 10779361283.0上面显示的示例生成


对于此示例gcc-m32 -S -O0 -fno-stack-protector -fno-asynchronous-unwind-tables使用英特尔设置与标志一起使用以生成程序集输出。

参考资料

带有编译标志和其他设置的编译器资源管理器链接

fuz*_*fuz 5

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

确定浮点数的 IEEE 754 表示对人类来说并非易事。在手写汇编代码中,使用.floator.double指令通常是个好主意:

.float 3.0    # generates 3.0 as a 32 bit float
.double 3.0   # generates 3.0 as a 64 bit float
Run Code Online (Sandbox Code Playgroud)

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

编译器在内部进行转换(四舍五入到最接近的可表示 FP 值),因为 FP 值通常不直接来自源中的文字;它们可以来自不断折叠。eg1.23 * 4.56在编译时被评估,所以编译器已经以浮点或双二进制表示的 FP 值结束。将它们打印回十进制以便汇编程序解析并重新转换为二进制会更慢,并且可能需要很多小数位。


要将 32 位浮点数表示为 32 位整数,您可以使用在线 IEEE754 转换器或如下程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • @janniks 我添加了一个执行此操作的程序。如果您曾经编写过汇编代码,请不要将浮点文字编码为整数。对于下一个人阅读您的代码来说,这真是太糟糕了。 (2认同)