Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
x64 の 64 ビットモードのエンコーディング概略
x64 の 64 ビットモードのエンコーディング概略
@tenpoku1000
2018/10/15 作成, 2020/08/18 最終更新
1. 命令の方向
初歩的な命令の場合:
ニーモニック ディスティネーション・オペランド, ソース・オペランド
例:
mov eax, 5
1.1. 方向(d)ビット
整数命令:d ビットは 1 バイト・プライマリ・オペコードのビット 1(0 origin)
x87 浮動小数点命令:d ビットはプライマリ・オペコードの第 1 バイトのビット 2(0 origin)
表1-1. 方向(d)ビットのエンコーディング(「3. ModR/M バイト」「4. SIB バイト」参照)
-----------------------------------------------------
d | ソース | デスティネーション
-----------------------------------------------------
0 | reg フィールド | ModR/M バイトまたは SIB バイト
-----------------------------------------------------
1 | ModR/M バイト | reg フィールド
| またはSIB バイト |
-----------------------------------------------------
2. 命令の構成
(1) レガシー・プリフィックス:必要な場合に指定(以下は、例)
65h: GS セグメント・オーバーライド・プリフィックス
(2) REX プリフィックス:0 または 1 バイト
40h ~ 4fh: 0100 WRXB
(3) オペコード:1, 2, 3 バイト
(4) ModR/M バイト:0 または 1 バイト(「3. ModR/M バイト」参照)
(5) SIB バイト:0 または 1 バイト(「4. SIB バイト」参照)
mod != 11, r/m の場合、RSP や R12 が指定できないので、SIB.Base = RSP または R12 を利用する場合に必要
(6) 変位(Address displacement):0, 1, 2, 4 バイト(一部の命令は 8 バイト)
・64 ビットに符号拡張される
・64 ビット絶対アドレス MOV 命令が使える
memory64 to RAX 0100 1000 1010 0001 : displacement64
RAX to memory64 0100 1000 1010 0011 : displacement64
(7) 即値(Immediate data):0, 1, 2, 4 バイト(一部の命令は 8 バイト)
・オペランドサイズが 64 ビットの場合、64 ビットに符号拡張される
・64 ビット即値 MOV 命令が使える
immediate64 to qwordregister 0100 100B 1011 1000 reg : imm64
3. ModR/M バイト
フォーマット:
mod(ビット 7, 6)
reg/Opcode(ビット 5, 4, 3)
r/m(ビット 2, 1, 0)
REX.W = 1 で、64 ビット幅のレジスタを指定できる。
reg または mod = 11, r/m REX.R = 1
-----------------------------------
000 0 EAX R8D
001 1 ECX R9D
010 2 EDX R10D
011 3 EBX R11D
100 4 ESP R12D
101 5 EBP R13D
110 6 ESI R14D
111 7 EDI R15D
基本的なアドレス指定モード:
mod mod != 11, r/m REX.B = 1
-----------------------------------------------
00 000 0 [RAX] [R8]
001 1 [RCX] [R9]
010 2 [RDX] [R10]
011 3 [RBX] [R11]
100 4 SIB有り SIB有り
101 5 RIP+disp32(*1,*2,*3) RIP+disp32(*1,*2)
110 6 [RSI] [R14]
111 7 [RDI] [R15]
-----------------------------------------------
01 000 0 [RAX + disp8] [R8 + disp8]
001 1 [RCX + disp8] [R9 + disp8]
010 2 [RDX + disp8] [R10 + disp8]
011 3 [RBX + disp8] [R11 + disp8]
100 4 SIB有り+disp8 SIB有り+disp8
101 5 [RBP + disp8] [R13 + disp8]
110 6 [RSI + disp8] [R14 + disp8]
111 7 [RDI + disp8] [R15 + disp8]
-----------------------------------------------
10 000 0 [RAX + disp32] [R8 + disp32]
001 1 [RCX + disp32] [R9 + disp32]
010 2 [RDX + disp32] [R10 + disp32]
011 3 [RBX + disp32] [R11 + disp32]
100 4 SIB有り+disp32 SIB有り+disp32
101 5 [RBP + disp32] [R13 + disp32]
110 6 [RSI + disp32] [R14 + disp32]
111 7 [RDI + disp32] [R15 + disp32]
*1. 変位 0 の mod = 01, r/m = 101 を利用して、変位なしの RBP または R13 を指定可能
*2. RIP 相対ではない、0 を基準とした disp32 は SIB バイトで指定可能(「4. SIB バイト」参照)
*3. REX プリフィックスの有無に影響されない
4. SIB バイト
フォーマット:
SIB.Scale(ビット 7, 6)
SIB.Index(ビット 5, 4, 3)
SIB.Base(ビット 2, 1, 0)
基本的なアドレス指定モード:
(SIB.Index * scale) + SIB.Base
SIB.Scale scale
----------------
00 0 1
01 1 2
10 2 4
11 3 8
base REX.B = 1 + base index REX.X = 1 + index
---------------------------------------------------------------
000 0 [RAX] [R8] [RAX] [R8]
001 1 [RCX] [R9] [RCX] [R9]
010 2 [RDX] [R10] [RDX] [R10]
011 3 [RBX] [R11] [RBX] [R11]
100 4 [RSP] [R12] none(*2) [R12]
101 5 [RBP](*1,*2) [R13] [RBP] [R13]
110 6 [RSI] [R14] [RSI] [R14]
111 7 [RDI] [R15] [RDI] [R15]
*1. mod 例外的なアドレス指定モード(1)
------------------------------------
00 (SIB.Index * scale) + disp32
01 (SIB.Index * scale) + disp8 + [RBP]
10 (SIB.Index * scale) + disp32 + [RBP]
*2. 例外的なアドレス指定モード(2)
mod base scale index 変位
-------------------------------------------------------
00 101 00, 01, 10, 11 100 0 を基準とした disp32
5. オペコードの reg フィールド
REX.W = 1 で、64 ビット幅のレジスタを指定できる。
reg REX.B = 1
--------------------
000 0 EAX R8D
001 1 ECX R9D
010 2 EDX R10D
011 3 EBX R11D
100 4 ESP R12D
101 5 EBP R13D
110 6 ESI R14D
111 7 EDI R15D
6. 参考資料
IA-32 インテル® アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル
上巻: 基本アーキテクチャ
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol1_Online_i.pdf
IA-32 インテル® アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル
中巻 A: 命令セット・リファレンス A-M
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol2A_i.pdf
IA-32 インテル® アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル
中巻 B: 命令セット・リファレンス N-Z
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol2B_i.pdf
インテル® エクステンデッド・メモリ 64 テクノロジ・ソフトウェア・ デベロッパーズ・ガイド
第 1 巻 リビジョン 1.1
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL1_30083402_i.pdf
インテル® エクステンデッド・メモリ 64 テクノロジ・ソフトウェア・ デベロッパーズ・ガイド
第 2 巻 リビジョン 1.1
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL2_30083502_i.pdf
Intel® 64 and IA-32 Architectures Software Developer Manuals | Intel® Software
https://software.intel.com/en-us/articles/intel-sdm
Intel® 64 and IA-32 Architectures Software Developer’s Manual
Volume 1: Basic Architecture rev.067 May 2018
Intel® 64 and IA-32 Architectures Software Developer’s Manual
Volume 2 (2A, 2B, 2C & 2D): Instruction Set Reference, A-Z rev.067 May 2018
@sisshiki1969

This comment has been minimized.

Copy link

@sisshiki1969 sisshiki1969 commented Sep 15, 2019

参考になりました。ありがとうございました。
3. ModR/M バイトの「基本的なアドレス指定モード」ですが、
[RAX]+disp8 => [RAX+disp8]
などとすべきかと思われます。

@tenpoku1000

This comment has been minimized.

Copy link
Owner Author

@tenpoku1000 tenpoku1000 commented Sep 15, 2019

ご指摘ありがとうございます。修正しておきました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment