释放x87 FPU堆栈(ia32)

时间:2013-11-10 16:39:08

标签: assembly floating-point x86 fpu x87

在我的大学,我们刚刚介绍了IA32 x87 FPU。但是我们没有被告知如何清除不再需要元素的FPU-Stack。

想象一下,我们正在执行一个简单的计算,如(5.6 * 2.4)+(3.9 * 10.3)。

.data
        value1: .float 5.6
        value2: .float 2.4
        value3: .float 3.8
        value4: .float 10.3

        output: .string "The result is: %f\n"

.text
.global main

main:
        fld     value1          # Load / Push 5.6 into FPU
        fmul    value2          # Multiply FPU's top (5.6) with 2.4
        fld     value3          # Load / Push 3.8 into FPU
        fmul    value4          # Multiply the top element of the FPU's Stacks with 10.3
        fadd    %st(1)          # Add the value under the top element to the top elements value

.output:
        # Reserve memory for a float (64 Bit)
        subl $8, %esp
        # Pop the FPU's top element to the program's Stack
        fstpl (%esp)
        # Push the string to the stack
        pushl $output
        # Call printf function with the both parameters above
        call printf
        # Free the programs stack from the parameters for printf
        addl $12, %esp

.exit:
        movl $1, %eax
        int $0x80

问题是:弹出FPU的顶部元素后,它保存了计算结果。如何从现有的新顶部元素释放FPU的堆栈,该元素保存(5.6 * 2.4)的结果。

我能够想象的唯一方法是从FPU的堆栈中释放更多的程序堆栈和弹出元素,直到不再需要的元素都被删除。

有没有办法直接操纵顶部指针?

4 个答案:

答案 0 :(得分:6)

要完成堆叠中没有任何garbadge,您需要使用FADDPFMULP以及类似说明。

答案 1 :(得分:5)

如果像我这样的人来到这里寻找清除堆栈的最佳方法,我发现这个简单的解决方案是最好的:

fstp ST(0) ; just pops top of the stack

答案 2 :(得分:2)

emms也可用于标记f.p.的每个成员。堆叠为免费。这比finit更有优势,它不会改变f.p中的任何标志。控制或状态字(例外掩码等)

答案 3 :(得分:1)

有几条指令可以执行您正在寻找的操作。 FDECSTP递减堆栈指针(不做任何其他操作),FFREE将一个槽标记为空(尽管没有触及堆栈指针)。上面提到的使用FADDPFMULP的解决方案通常更好。

您应该考虑下载Intel Architecture Manuals。它们包含Intel CPU系列的完整指令集。