それを印刷メモリからロードするか、またはメモリにのみ保存できる積み重ねられたレジスタセットを使用したことに注意してください。
Intel manual 1を使用するか、ノスタルジックな感じがある場合はreading this 387 manual from Intel dated 05/26/1987のいずれかを使用して、FPUプログラミングモデルについてドキュメント化することができます。
命令fstp dword [eax]
アドレスがeax
でを示さでst(0)
の内容を保存します。この種のアドレッシングモードは、間接アドレッシングモードであり、インテルアセンブリ構文で角括弧を使用して一貫してマークされています。
st(0)
をeax
に保存すると、これはfstp eax
(角括弧は不要)のようになります。
後者はサポートされていない可能性があります。これは、FPUが、当時、レジスタに適合できなかった64ビットと80ビットのフォーマットをサポートしているからです。
データをプッシュする。メモリからFPUスタックへfld
を使用し、レジスタをメモリにポップアップさせ、fstp
(またはスタックをポップしたくない場合はfst
)を使用します。
乗算にはfmul
を使用しますが、いくつかの変形があります。その1つはメモリオペランドで演算し、その結果を直接st(0)
に格納することができます。
このプログラムは、プログラムの開始時にfinit
を使用することができます。この命令は、FPUの制御レジスタをリセットしてレジスタを空にするように設定します。
OSはすでにクリーンな状態でプロセスを開始する必要があります。ここでは簡単な例
:今日のよう .DATA
A dd 5.0
B dq 0.008
C dd 0 ;Move into a BSS section if the assembler support it
.CODE
finit ;For paranoid only
fld DWORD [A] ;ST(0) = A
fmul QWORD [B] ;ST(0) = ST(0)*B = A*B
fstp DWORD [C] ;C = ST(0) = A*B
mov eax, DWORD [C] ;EAX = C = A*B
call writefloat
あなたはスカラ命令とベクトルレジスタを使用することができます。
関連ドキュメントは、以前にリンクされたIntelのマニュアルに記載されています。
.DATA
A dd 5.0 ;Use float
B dd 0.008 ;Use float again, avoid cvtss2sd
C dd 0 ;Move into a BSS section if the assembler support it
.CODE
movss xmm0, DWORD PTR [A] ;xmm0.f[0] = A
mulss xmm0, DWORD PTR [B] ;xmm0.f[0] = A * B
movd eax, xmm0 ;eax = xmm0.f[0] = A * B
;Beware, 1 extra cycle for bypass delay
call writefloat
このコードは 'fin'を読み込み、' fin'で乗算します。これはfin^2(二乗)と同じです。あなたの 'fmul'は' fin * * 'を乗算したい値をオペランドとして取るべきです。しかし、コードは質問と一致しません。なぜなら、 'fin'は定数5.0なので、あなたは3.02 x 0.008を乗算することを話しています。 –