9

在我的大学里,我们刚刚被介绍到 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

4 回答 4

7

FADDP要做到这一点,您需要使用andFMULP和类似的指令在堆栈上没有任何垃圾。

于 2013-11-10T16:59:07.183 回答
7

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

fstp ST(0) ; just pops top of the stack
于 2015-11-06T21:18:15.843 回答
3

emms 也可用于将 fp 堆栈的每个成员标记为空闲。与 finit 相比,它的优势在于它不会更改 fp 控制或状态字中的任何标志(异常掩码等)

于 2017-06-24T16:12:29.650 回答
1

有几个指令可以执行您正在寻找的操作。FDECSTP递减堆栈指针(不做任何其他事情),FFREE将插槽标记为空(但不接触堆栈指针)。不过,上面提到的使用FADDPor的解决方案FMULP通常更好。

您应该考虑下载英特尔架构手册。它们包含 Intel CPU 系列的完整指令集。

于 2013-11-10T17:03:54.727 回答