12

最近、FPUスタックオーバーフローで問題が発生しています。呼び出されるたびにガベージ値をFPUスタックにプッシュし、クリーンアップしないバグのあるライブラリ関数まで追跡することができました。

幸いなことに、これは簡単に再現でき、どのような条件が原因であるかを正確に把握しています。インラインASMのブロックを、このルーチンを呼び出すルーチンにドロップして、FPUスタックから最上位の値をポップバックすることができます...何を書くべきかよくわからない場合を除きます。私のASM-fuは中途半端なものですが、それほど強力はありません。

では、x86アセンブリでFPUスタックの最上位の値を削除する最も簡単な方法は何ですか?それがガベージデータであり、値を気にしないと仮定しますか?

4

4 に答える 4

13

Delphi / BASMの場合、私の見解では、FPUスタックを一度ポップする最も簡単な方法は次のとおりです。

asm
 fstp st(0)
end;
于 2011-01-26T21:53:20.943 に答える
9

スタックを調整する必要がある量がわかっている場合は、を使用できますfincstp。またffree、インクリメントするレジスタも必要です。

ただし、おそらく最も簡単な解決策は、のようなポップデータ転送操作の1つを使用することfstpです。通常、結果を後で使用するためにメモリの領域に保存します。たとえば、次のようになります。

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

ただし、値を破棄したいだけの場合は、st(0)それ自体を宛先として使用して、メモリ要件を節約できます。

fstp st(0)

手順の詳細なガイド(特にこのビット)については、ここを参照してください。

于 2011-01-23T05:11:33.477 に答える
4

st0が使用中の唯一のx87レジスタである場合は、次のコマンドで空にすることができます。

ffree st0

ただし、これは、スタックの最上位ポインター(x87ステータスワードのTOPフィールド)を調整しないため、複数のスタックレジスタが使用されている場合の通常のポップとは異なります。

SimplyFPUx87チュートリアルのレジスタの章を参照してください。

st1st1ポップする代わりに解放した後でもそうなるst0ので、これは通常あなたが望むものではなく、に比べて大きな利点はありませんfstp st0

于 2011-01-23T13:36:57.267 に答える
2

ポップする(高速の)命令でスタックからポップするだけです。 8087命令セット

それが機能しない場合、FUCOMPPは2回ポップします。

于 2011-01-23T05:30:33.130 に答える