質問

私は最近、FPUスタックのオーバーフローでいくつかの問題を抱えています。私はそれをなんとかバギーライブラリ関数に戻しました。バギーライブラリ関数は、呼び出されるたびにゴミ値をFPUスタックに押し上げ、決してクリーンアップしません。

幸いなことに、これは簡単に再現でき、どの条件が原因であるかを正確に知っています。インラインASMのブロックをルーチンにドロップし、このルーチンを呼び出してFPUスタックから最上位の値をポップします...何を書くべきかわからないことを除いて。私のASM-FUはミッドリンに公平ですが、そうではありません それ 強い。

それでは、X86アセンブリのFPUスタックの最高値を取り除く最も簡単な方法は何ですか。それがゴミデータであり、私が値を気にしないと仮定していますか?

役に立ちましたか?

解決

スタックを調整する必要があるかどうかを知っている場合は、使用できます fincstp. 。あなたもしたいです ffree あなたが増やすレジスタ。

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

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

しかし、あなたが価値を捨てたいだけであることを知っているなら、あなたは使用することができます st(0) 目的地としてのそれ自体、メモリ要件を保存します。

fstp st(0)

見る ここ 指示に関する詳細なガイドについては(特に このビット).

他のヒント

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

asm
 fstp st(0)
end;

もしも st0 使用中の唯一のx87レジスタは、次のことを空にすることができます。

ffree st0

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

見る Simply FPU X87チュートリアルのレジスタの章.

st1 まだあるでしょう st1 解放後 st0 ポップする代わりに、これは通常あなたが望むものではなく、重要な利点はありません fstp st0.

ポップする(高速)命令でスタックからポップしてください。8087命令セット

それがうまくいかない場合、Fucomppは2回ポップします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top