• 検索結果がありません。

IA-32 インテル ®

8.1.1. x87 FPU データ・レジスタ

TOPが0の場合にロード操作が実行されると、レジスタはラップアラウンドし、TOPの新しい値が7 にセットされる。ラップアラウンドによってセーブされていない値が上書きされる可能性がある場 合は、浮動小数点スタック・オーバーフロー例外によって示される(8.5.1.1.項「スタック・オーバー フロー例外またはスタック・アンダーフロー例外 (#IS)」を参照)。

浮動小数点命令の多くではいくつかのアドレス指定モードが用意されていて、プログラマはスタッ クのトップに対して暗黙的に操作するか、特定のレジスタに対してはTOPに相対させて明示的に操 作することができる。アセンブラはこれらのレジスタ・アドレス指定モードをサポートしており、

ST(0)(あるいは単にST)という表現を使って現在のスタックのトップを表し、ST(i)という表現を

使ってスタック内のTOPからi番目(0≦ i ≦7)のレジスタを指定する。たとえば、TOPに011Bが 格納されている場合(スタックのトップがレジスタ3)、次の命令は、スタック内の2つのレジスタ

(レジスタ3と5)の内容を加算する。

FADD ST, ST(2);

図8-3.に、一連の計算を実行する場合に、x87 FPUレジスタのスタック構造や命令が一般的にどのよ うに使用されるか、例を挙げて示す。この例では、2次元のドット積が次のように計算される。

1. 最初の命令(FLD value1)が、スタック・レジスタ・ポインタ(TOP)をデクリメントし、値 5.6をメモリからST(0)にロードする。この操作の結果をスナップショット(a)に示す。

2. 2番目の命令が、ST(0)内の値をメモリからロードした値2.4で乗算し、その結果をST(0)に格 納する。この操作の結果をスナップショット(b)に示す。

3. 3番目の命令がTOPをデクリメントし、値3.8をST(0)にロードする。

4. 4番目の命令がST(0)内の値をメモリからロードした値10.3で乗算し、その結果をST(0)に格納 する。この操作の結果をスナップショット(c)に示す。

5. 5番目の命令が、このST(0)の値とST(1)の値を加算し、その結果をST(0)に格納する。この操 作の結果をスナップショット(d)に示す。

図8-2. x87 FPUデータ・レジスタ・スタック

7 6 5 4 3 2 1 0

FPUデータ・レジスタ・スタック

ST(2) ST(1) ST(0)

Top 011B スタックの

増大方向

この例に示したプログラミング・スタイルは、浮動小数点命令セットによってサポートされる。ス タック構造が計算上のボトルネックとなるような場合は、FXCH (Exchange x87 FPU register contents)

命令を使用して計算を一本化できる。

8.1.1.1. x87 FPUレジスタ・スタックとのパラメータの受け渡し

汎用レジスタと同じように、x87 FPUデータ・レジスタの内容もプロシージャ・コールの影響を受け ない。すなわち、これらのレジスタの値はプロシージャの境界を越えて保持される。このため、コー ル元プロシージャは、x87 FPUデータ・レジスタ(およびプロシージャ・スタック)を使用すること で、プロシージャ間でパラメータを受け渡すことができる。コールされたプロシージャがレジスタ・

スタックを介して渡されるパラメータを参照する場合は、現在のスタック・レジスタ・ポインタ

(TOP)と、ST(0)ならびにST(i)の表現を使用できる。さらに、一般的に行われている技法として、

コール元のプロシージャやプログラムに実行を戻す際に、コールされたプロシージャがリターン値 や結果をレジスタST(0)に残しておくこともできる。

プロシージャまたはコード・シーケンス内でMMX命令とx87 FPU命令を混在させる場合、プログラ

マは、x87 FPUデータ・レジスタ内で渡されるパラメータの整合性を維持する責任を負う。x87 FPU

データ・レジスタ内のパラメータが他のプロシージャに渡される前にMMX命令が実行されると、そ れらのパラメータは失われる(9.5.節「x87 FPUアーキテクチャとの互換性」を参照)。

図8-3. x87 FPUによるドット積の計算例

(a) R7 R6 R5 R4 R3 R2 R1 R0

計算

ST(0) 5.6

(b) R7 R6 R5 R4 R3 R2 R1 R0

ST(0) 13.44

(c) R7 R6 R5 R4 R3 R2 R1 R0

ST(1) ST(0) 13.44

(d) R7 R6 R5 R4 R3 R2 R1 R0

ST 39.14 ST

13.44 52.58 ドット積= (5.6 x 2.4) + (3.8 x 10.3)

コード:

FLD value1 ;(a) value1=5.6 FMUL value2 ;(b) value2=2.4 FLD value3 ; value3=3.8 FMUL value4 ;(c)value4=10.3 FADD ST(1) ;(d)