从 FPU 堆栈中删除某些内容的最简单方法
最近我在 FPU 堆栈溢出方面遇到了一些麻烦。我设法将其追溯到一个有缺陷的库函数,该函数每次调用时都会将垃圾值推送到 FPU 堆栈上,并且从不清理它。
幸运的是,这很容易重现,而且我确切地知道是什么条件导致的。我可以将一个内联 ASM 块放入调用此例程的例程中,以将顶部值从 FPU 堆栈中弹出……但我不太知道要写什么。我的 ASM 能力还算中等,但没有那么强。
那么,假设 x86 程序集中 FPU 堆栈上的顶部值是垃圾数据并且我不关心该值,那么最简单的方法是什么?
I've been having some trouble lately with FPU stack overflows. I managed to track it back to a buggy library function that pushes a garbage value onto the FPU stack every time it's called and never cleans it up.
Fortunately, this is easily reproducible and I know exactly what conditions cause it. I can drop a block of inline ASM into the routine that calls this routine to pop the top value back off the FPU stack... except I don't quite know what to write. My ASM-fu is fair to middlin', but not that strong.
So what's the simplest way to get rid of the top value on the FPU stack in x86 assembly, assuming it's garbage data and I don't care about the value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于 Delphi/BASM,我认为弹出 FPU 堆栈一次的最简单方法是:
For Delphi/BASM, in my view the simplest way to pop the FPU stack once is:
如果您知道需要调整堆栈多少,可以使用
fincstp
。您还希望ffree
您递增的寄存器。然而,最简单的解决方案可能是使用弹出数据传输操作之一,例如
fstp
。通常,您会将结果存储到内存区域中以供以后使用,例如:但是,如果您知道只想丢弃该值,则可以使用
st(0)
本身作为目标,节省内存要求:请参阅此处,了解有关说明的详细指南(特别是< a href="http://www.website.masmforum.com/tutorials/fptute/fpuchap4.htm#fstp" rel="noreferrer">这一点)。
If you know how much you need to adjust the stack by, you can use
fincstp
. You also want toffree
the registers that you increment over.However, probably the simplest solution is to use one of the popping data transfer operations like
fstp
. Normally you would store the result into an area of memory for later use, something like:But, if you know you just want to throw away the value, you can use
st(0)
itself as the destination, saving the memory requirement:See here for a detailed guide on the instructions (particularly this bit).
如果
st0
是唯一正在使用的 x87 寄存器,您可以使用以下命令清空它:但是,如果有多个堆栈寄存器正在使用,这与普通弹出不同,因为它不会调整顶部-堆栈指针(x87 状态字中的 TOP 字段)。
请参阅Simply FPU x87 教程的寄存器章节。
释放
st0
而不是弹出后,st1
仍然是st1
,因此这通常不是您想要的,并且与相比没有显着优势fstp st0。
If
st0
is the only x87 register in use, you can empty it with:But this is different from a normal pop if there are multiple stack registers in use, because it doesn't adjust the top-of-stack pointer (TOP field in the x87 status word).
See the registers chapter of the Simply FPU x87 tutorial.
st1
would still best1
after freeingst0
instead of popping, so this is normally not what you want and has no significant advantage overfstp st0
.只需使用弹出的任何(快速)指令将其从堆栈中弹出即可。
8087 指令集
如果这不起作用,FUCOMPP 会弹出两次。
just pop it off the stack with any (fast) instruction that pops.
8087 instruction set
if that doesn't work, FUCOMPP pops twice.