各演算処理をある程度まとめた状態にし、レジスタスタックに空きを作れば、問題は起き難くなります。
先に呼び出し側の演算を済ませてから floatex.dll の演算を行う.
_asm{
fld1 ; @
fld1 ; A
fld1 ; B
fld1 ; C
fld1 ; D
fld1 ; E
fld1 ; F
fld1 ; G
faddp st(1),st ; G
faddp st(1),st ; F
faddp st(1),st ; E
faddp st(1),st ; D
faddp st(1),st ; C
faddp st(1),st ; B
faddp st(1),st ; A
fstp tbyte ptr v ; @
}
floatex_eadd(fex_const_10,fex_const_2,t);
必要なレジスタスタックの空きは関数により異なるので、安全な演算を行うためには、レジスタスタックを全て空けておいてください。
|
演算処理にバグがあると、ポップされなかったレジスタが積み上がり、後にスタックフォルトの形で現れる事があります。演算終了時にレジスタスタックが空になる想定をしている場合は、次のように floatex_isempty を使用すると、正しくポップされている事を確認する事ができます。
・
・
・
faddp st(1),st ; B
faddp st(1),st ; A
fstp tbyte ptr v ; @
}
#ifdef DEBUG
/*
表示内容:
1 ... 全て空 / 0 ... 1 つ以上使用 / -1 ... スタックフォルト
*/
printf("レジスタスタック状況:%d\n",floatex_isempty());
#endif
演算処理の後で floatex_stinit や floatex_reset 等を実行してレジスタスタックをクリアすると、スタックフォルトの問題を回避する事ができます。方法としては簡単なので、応急の修正には便利ですが、根本的な解決にはならない事に注意が必要です。また、本来なら行う必要の無いクリア処理が、演算を行う毎に入る事になるので、パフォーマンスに影響する可能性があります。