释放x87 FPU堆栈(ia32)

tmu*_*sch 7 floating-point x86 assembly 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

Quo*_*nux 6

为了实现这个目标你没有,你需要使用堆栈上的任何garbadge FADDPFMULP和类似的指令.

  • 事实上,使用堆栈作为你的优势,例如.计算A*B + C*D你做A推; m B; 推C; mulp D; ADDP (4认同)

Dan*_* M. 6

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

fstp ST(0) ; just pops top of the stack
Run Code Online (Sandbox Code Playgroud)

  • 或者“FNINIT”清除“所有”FP 寄存器,无论之前使用了多少个。但是,是的,“fstp st(0)”是“只是”弹出堆栈顶部并丢弃结果的最有效方法。 (2认同)