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

Floating point 程序集IA32:将4字节浮点从堆栈移动到FPU,floating-point,fpu,x86,Floating Point,Fpu,X86,在我的大学里,我们被介绍使用At&T语法的IA32/x86汇编程序。但这一解释缺乏重要信息 如何将4字节浮点从堆栈移动到FPU?我试过使用FLD,但没有达到预期效果 示例代码: .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 pri

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

如何将4字节浮点从堆栈移动到FPU?我试过使用FLD,但没有达到预期效果

示例代码:

.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


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

我认为问题在于(在调用
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

我认为问题在于(在调用
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