从FPU堆栈中删除内容的最简单方法

时间:2011-01-23 04:59:01

标签: assembly x86 x87

最近我在使用FPU堆栈溢出时遇到了一些麻烦。我设法将它追溯到一个错误的库函数,每次调用它时都会将垃圾值推送到FPU堆栈上,并且永远不会清理它。

幸运的是,这很容易重现,而且我确切地知道导致它的条件。我可以将一行内联ASM放入调用此例程的例程中,将最高值从FPU堆栈中弹回...除了我不太清楚要写什么。我的ASM-fu公平对待middlin',但 强大。

那么在x86程序集中摆脱FPU堆栈顶部值的最简单方法是什么,假设它是垃圾数据并且我不关心它的值?

4 个答案:

答案 0 :(得分:13)

对于Delphi / BASM,在我看来,弹出FPU堆栈的最简单方法是:

asm
 fstp st(0)
end;

答案 1 :(得分:7)

如果您知道需要多少调整堆栈,可以使用fincstp。您还希望ffree递增的寄存器。

但是,最简单的解决方案可能是使用其中一种弹出数据传输操作,如fstp。通常,您会将结果存储到内存区域以供以后使用,例如:

mem_area: defs 10         ; ten bytes for 80 bits
          fstp mem_area   ; pop it

但是,如果您知道自己只想丢弃该值,则可以使用st(0)本身作为目标,从而节省内存需求:

fstp st(0)

有关说明的详细指南(请参阅here),请参阅this bit

答案 2 :(得分:4)

如果st0是唯一正在使用的x87寄存器,则可以使用以下内容清空它:

ffree st0

但是如果使用多个堆栈寄存器,这与普通pop不同,因为它不调整堆栈顶部指针(x87状态字中的TOP字段)。

请参阅the registers chapter of the Simply FPU x87 tutorial

在释放st1而不是弹出后,

st1仍为st0,因此这通常不是您想要的,并且与fstp st0相比没有明显的优势。

答案 3 :(得分:2)

只需弹出任何(快速)指令就可以将其弹出堆栈。 8087 instruction set

如果不起作用,FUCOMPP弹出两次。