1

在我的大学,我们被介绍到使用 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 ......

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

4

1 回答 1

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
于 2013-11-13T21:22:55.537 回答