程序集IA32:将4字节浮点数从堆栈移到FPU

时间:2013-11-13 18:40:52

标签: floating-point x86 fpu ia-32

在我的大学,我们将使用AT& T语法向IA32 / x86汇编程序介绍。但解释缺乏重要信息。

如何将4字节的浮点数从堆栈移到FPU?我试过flds但它没有按预期工作......

示例代码:

.data
        fl:     .float 12.412
        test:   .string "Result: %f\n"

.text
.global main

main:
        # Prepare the stack (8 byte so i can use it for printf later)
        subl $8, %esp
        # Load the variable fl which holds 12.412
        fld fl
        # Store the previously loaded value as single precision (4 byte) to the stack
        fstps (%esp)
        # Load the value from the stack again and expect it to be single precision (as flds ends with s)
        flds (%esp)


        # Push it to the stack again. But this time as double precision value als printf expects floats to be 8 bytes long 
        fstp (%esp)
        pushl $test
        call printf

        movl $1, %eax
        int $0x80

但输出是:

结果:-0.491594

而不是预期的12.412 ......

[编辑:]有趣的事实。令人惊讶的是,每次执行该程序时结果都会发生变化。

1 个答案:

答案 0 :(得分:1)

我认为问题是(在你调用printf之前)你使用错误的指令将FPU的顶部弹出到堆栈上。你的评论说“......这次是双精度......”,但你实际用fstp做的是存储单精度值。试试fstpl,它会存储一个双精度值。

固定代码应如下所示:

.data
        fl:     .float 12.412
        test:   .string "Result: %f\n"

.text
.global main

main:
        subl $8, %esp
        fld fl
        fstps (%esp)
        flds (%esp)

        fstpl (%esp)        # This line is the only one that has been changed.
        pushl $test
        call printf

        movl $1, %eax
        int $0x80