1

x87FPU命令のデコードに関してあいまいなケースに直面しています。Vol2AIntelの命令セットマニュアル[1]の3-380ページから抜粋した次の命令を参照してください。

D9 /0    --> FLD m32fp --> Push m32fp onto the FPU register stack.
D9 C0+i  --> FLD ST(i) --> Push ST(i) onto the FPU register stack.

これらの命令は両方とも同じシングルバイトベースのオペコードを持っています0xD9。最初の命令の拡張オペコードは0x00。です。拡張オペコードは、ModR/Mバイトの「reg」フィールドで指定されます。ただし、2番目の命令は、「レジスタを取得するために追加」機能を備えた2バイトのオペコードです。この意味は:

D9 C0  --> FLD ST0  
D9 C1  --> FLD ST1  
(and so on)

これら2つの指示を区別することに関して私は小さな問題を抱えています。小さな例は次のとおりです。

ここで、オペコードシーケンスを取得するとします"D9 C1"。それが命令"FLD m32fp"であるかどうかを確認する必要がある場合は、ModR/Mバイトの「reg」フィールドが0x00であるかどうかを確認する必要があります。もしそうなら、それは確か"FLD m32fp"に使用されている命令です。

のバイナリ表現はC1です"1100 0001"。bit0がLSBであるとすると、bit3-bit5(両端を含む)はModR/Mバイトの「reg」フィールドを構成します"C1"0x00確かに(3つのゼロ)であることがわかります。

そこで、オペコードシーケンス"D9 C1"を命令にマッピングし"FLD m32fp"ます。"ecx"さらにデコードすると、この場合、オペランドが実際になることがわかります。しかし、これに"FLD ST1"もオペコードシーケンス"D9 C1"があり、これがそのオペコードシーケンスに使用されている実際の命令であることがわかります。

"D9 C1"本質的に、オペコードシーケンスが命令に対応し、では"FLD ST1"ないことをどのように確認でき"FLD ecx"ますか?

"FMUL"ここと同じようにオペランドをとるので、命令についても非常によく似た問題が発生"FLD"します。

[1] http://www.intel.com/design/intarch/manuals/243191.HTM

よろしくお願い
いたします。HrishikeshMurali

4

1 に答える 1

5

これについては、「A.2.6. エスケープ オペコード命令」で説明されています。関連する部分は次のとおりです。

ModR/M バイトが 00H ~ BFH の範囲内にある場合、ModR/M バイトのビット 5、4、および 3 は、1 バイトおよび 2 バイトのオペコードに使用される手法と同様に、オペコード拡張として使用されます (セクション A.2.5.「1 バイトおよび 2 バイト オペコードのオペコード拡張」)。ModR/M バイトが 00H ~ BFH の範囲外にある場合、ModR/M バイト全体がオペコード拡張として使用されます。

質問に:

ここで、オペコード シーケンス "D9 C1" を取得したとします。「FLD​​ m32fp」命令かどうかを確認する必要がある場合は、ModR/M バイトの「reg」フィールドが 0x00 かどうかを確認する必要があります。もしそうなら、それは実際に使用されている命令「FLD m32fp」です。

x87 命令に遭遇した場合、mod/rm バイトが >= 0xC0 (0b11 または 3 の mod フィールドに対応) であるかどうかを確認する必要があります。その場合は、表 A-10 (D9 の場合) で調べます。そこを見ると、それがわかりますD9 C1 = FLD ST(0),ST(1)

mod/rm バイトが < 0xC0 の場合、使用するテーブルは A-9 です。D9 01(mod = 0b00, opcode extension (reg) = 0b000, rm = 0b001) は「FLD single-real」であり、表 2-2 を見るとfld dword [ecx].

余談ですが、整数レジスタから FPU スタックに直接ロードできないため、「FLD ecx」などの命令はありません。

于 2011-11-21T06:46:28.223 に答える