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

发布于 2024-10-13 19:44:51 字数 266 浏览 3 评论 0原文

最近我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只为守护你 2024-10-20 19:44:51

对于 Delphi/BASM,我认为弹出 FPU 堆栈一次的最简单方法是:

asm
 fstp st(0)
end;

For Delphi/BASM, in my view the simplest way to pop the FPU stack once is:

asm
 fstp st(0)
end;
云归处 2024-10-20 19:44:51

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

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

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

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

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 to ffree 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:

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

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:

fstp st(0)

See here for a detailed guide on the instructions (particularly this bit).

镜花水月 2024-10-20 19:44:51

如果 st0 是唯一正在使用的 x87 寄存器,您可以使用以下命令清空它:

ffree st0

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

请参阅Simply FPU x87 教程的寄存器章节

释放 st0 而不是弹出后,st1 仍然是 st1,因此这通常不是您想要的,并且与 相比没有显着优势fstp st0。

If st0 is the only x87 register in use, you can empty it with:

ffree st0

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 be st1 after freeing st0 instead of popping, so this is normally not what you want and has no significant advantage over fstp st0.

云巢 2024-10-20 19:44:51

只需使用弹出的任何(快速)指令将其从堆栈中弹出即可。
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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文