我最近在 FPU 堆栈溢出方面遇到了一些麻烦。我设法将其追溯到一个有缺陷的库函数,该函数每次调用时都会将垃圾值推送到 FPU 堆栈上,并且从不清理它。
幸运的是,这很容易重现,我确切地知道是什么条件造成的。我可以将一个内联 ASM 块放入调用该例程的例程中,以将顶部值从 FPU 堆栈中弹出……除非我不太清楚该写什么。我的 ASM-fu 还算中规中矩,但没那么强。
那么,假设它是垃圾数据并且我不关心该值,那么在 x86 程序集中摆脱 FPU 堆栈上的最高值的最简单方法是什么?
对于 Delphi/BASM,在我看来,一次弹出 FPU 堆栈的最简单方法是:
asm
fstp st(0)
end;
如果st0
是唯一正在使用的 x87 寄存器,您可以使用以下命令清空它:
ffree st0
但是,如果有多个堆栈寄存器在使用中,这与普通弹出不同,因为它不会调整栈顶指针(x87 状态字中的 TOP 字段)。
st1
仍然会st1
在释放st0
而不是弹出之后,所以这通常不是你想要的,并且与fstp st0
.
只需使用弹出的任何(快速)指令将其从堆栈中弹出。 8087指令集
如果这不起作用,FUCOMPP 会弹出两次。