x86-64
バイナリコードフォーマット
ロングモードで実行されるバイナリコードは以下のフォーマットです.つまり,コンパイラ・アセンブラで出力されるネイティブの実行コードは.以下のフォーマットになっています.
- Legacy prefixes (Grp 1, 2, 3, 4; optional):最大4バイト
- REX Prefix (optional)
- Opcode (1-3 bytes)
- ModR/M (1 byte if required)
- SIB (1 byte if required)
- Displacement (1,2,4 bytes or none)
- Immediate (1,2,4,8 bytes or none)
オペコードはOpcodeに,オペランドはModR/M,SIB,Displacement,Immediateにエンコードされています.
ここで,REXプレフィックスは,32ビットアーキテクチャには現れなかったプレフィックスなので,説明します.REXプレフィックスは 0b0100WRXB (W,R,X,Bはそれぞれ1ビット)というフォーマットで,W,R,X,B,それぞれのビットはREX.W, REX.R,REX.X,REX.Bのように表現されます.
REX.Wはオペランドの実効サイズを変更します.REX.Wが0のときはオペランドの実効サイズはコードセグメントのDフラグによって決定されますが,1のときはオペランドの実効サイズは64ビットとなります.
REX.R,REX.X,REX.Bは,オペランドにx86-64で追加された汎用レジスタR8–R15を指定するための拡張フラグです.REX.RはModR/Mのレジスタ拡張フラグです.REX.Rが1のとき,ModR/MのレジスタはR8–R15を表します.REX.XはSIBのScale index拡張フラグです.REX.Xが1のとき,SIBのScale indexはレジスタはR8–R15を表します.REX.BはModR/Mのr/mフィールドまたはSIBのBaseレジスタの拡張フラグです.REX.Bが1のとき,これらはレジスタはR8–R15を表します.gas記法のアセンブラで各フラグが影響するフィールドを表すと,エンコードがRMまたはMRの例では,
REX.R reg,disp(REX.B base,REX.X offset,scale)
または
disp(REX.B base,REX.X offset,scale),REX.R reg
のようになります.