最近我在使用FPU堆栈溢出时遇到了一些麻烦。我设法将它追溯到一个错误的库函数,每次调用它时都会将垃圾值推送到FPU堆栈上,并且永远不会清理它。
幸运的是,这很容易重现,而且我确切地知道导致它的条件。我可以将一行内联ASM放入调用此例程的例程中,将最高值从FPU堆栈中弹回...除了我不太清楚要写什么。我的ASM-fu公平对待middlin',但 强大。
那么在x86程序集中摆脱FPU堆栈顶部值的最简单方法是什么,假设它是垃圾数据并且我不关心它的值?
答案 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)
答案 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弹出两次。