[解決済み] ST(0)をEAXに移動させる方法は?
質問
こんにちは、私はx86 FPUのアセンブリを学んでいます。 簡単な質問で、答えが見つからないものがあります。
から値を移動させる方法
ST(0)
( FPUのトップ
スタック)から
EAX
?
もあります。
はこのコードで合っていますか?
; multiply (dot) two vectors of 3 floats passed by pointers as arg 1 arg 2
; passings are ok I think, but not sure if multiplies-adds are ok
push ebp
mov ebp, esp
mov eax, dword [ebp+8H]
mov edx, dword [ebp+0CH]
fld qword [eax]
fmul qword [edx]
fld qword [eax+4H]
fmul qword [edx+4H]
fld qword [eax+8H]
fmul qword [edx+8H]
faddp st1, st(0)
faddp st1, st(0)
fstp qword [ebp+10H] ; here I vould prefer 'mov eax, st0'
pop ebp
ret
解決方法は?
そうしなければならない本当の理由はありません。次のことを忘れないでください。
EAX
は32ビットレジスタですが、FPUのレジスタはすべて80ビット幅です。これは、FPUがデフォルトで80ビット浮動小数点数で計算を行うからです。そのため、FPUレジスタから汎用レジスタにデータを移動すると、データロスが発生します。どうしてもそういうことをしたい場合は、次のようにしてみてください(スタックスペースに余裕があることが前提です).
sub esp, 4 ; or use space you already reserved
fstp dword [esp]
mov eax, [esp] ; or better, pop eax
add esp, 4
この命令は、現在FPUスタックの一番上にあるfloatを32ビットに丸め、それを一時的なスタックロケーションに書き込み、FPUスタックにロードします。
float
(binary32)ビットパターンを
EAX
そして、使用したスタック領域を整理する。
このようなことは、ほとんどありません。
標準的な呼び出し規約では、float / double / long doubleの値は
st(0)
そのため、Cコンパイラはそこに
double foo()
関数が値を残すようにします。 (または
xmm0
SSE/SSE2 の場合)。
FPのビットパターンで整数の操作やテストをしたい場合にのみ必要です。 (例: Cでタイプパンを実装する場合
memcpy
から
float
から
uint32_t
). 例)
有名ですが、今ではほとんど使われなくなった高速近似逆引きの
sqrtf
マジックナンバーハック
Quakeのソースコードで使用されています。
関連
-
[解決済み】バイナリーボム - フェーズ4
-
[解決済み] テスト
-
[解決済み] MIPS: スタックポインタ($sp)とスタックの関連した使用法
-
[解決済み] MIPSでディブディブ
-
[解決済み] アセンブリ言語で数字をプリントアウトする?
-
[解決済み] アセンブリ命令のトラップは何をするのですか?
-
[解決済み] SRLとSRAの違いは何ですか?[重複しています]。
-
ファイルまたはアセンブリを読み込めませんでした ... 不正なフォーマットでプログラムをロードしようとしました。
-
[解決済み] 未解決のシンボルが残る コードコンポーザースタジオ
-
[解決済み] eax に対して `testl` eax?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン