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

时间:2018-06-06 20:29:23

标签: c assembly floating-point x86 ieee-754

以下C代码:

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

转换为以下装配说明:

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

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

对于上面显示的示例,从1077936128生成的

例如 3.0

  

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

参考

带有编译标志和其他设置的

Compiler Explorer Link

1 个答案:

答案 0 :(得分:4)

x86 FPU硬件使用float / double的{​​{3}} / binary64表示。

确定浮点数的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

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

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

要计算32位浮点数作为32位整数的表示形式,可以使用explanations on Wikipedia或类似的程序:

#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;
}