Skip to content
Hideaki Takahashi edited this page Apr 20, 2024 · 37 revisions

Welcome to the MyDisassembler wiki!

命令のフォーマット

x86-64の命令は一般的に以下のような構成となっている。

|prefix | REX prefix  |     opecode      |   ModR/M    |   SIB       |     address offset     |      immediate         |
|-------|-------------|------------------|-------------|-------------|------------------------|------------------------|
|       | 0 or 1 byte | 1, 2, or 3 bytes | 0 or 1 byte | 0 or 1 byte | 0, 1, 2, 3, or 4 bytes | 0, 1, 2, 3, or 4 bytes |

転送命令では、転送元が右側、転送先の左側に来る。

    mov   rax, 1234567890          ; rax = 1234567890
    mov   rax, [rsi + rdi * 4]     ; rax = Memory[rsi + rdi * 4]
    mov   rax, rbx                 ; rax = rbx
    mov   [rsi + rdi * 4], rax     ; Memory[rsi + rdi * 4] = rax

演算命令では、左側に結果が格納される。

    add   rax, 1234567890          ; rax = rax + 1234567890
    add   rax, [rsi + rdi * 4]     ; rax = rax + Memory[rsi + rdi * 4]
    add   rax, rbx                 ; rax = rax + rbx
    add   [rsi + rdi * 4], rax     ; Memory[rsi + rdi * 4] = Memory[rsi + rdi * 4] + rax

メモリアドレスは、ベースレジスタ + インデックスレジスタ * スケール + 定数という形式で指定することができる。

REX Prefix

bit   |0|1|2|3|
------|-|-|-|-|
field |B|X|R|W|
フィールド名 | ビット位置 | 定義
------------|-----------|-----------------------------------------------------------------
         B  |         0 | ModRM の r/m、SIB の base、またはオペコードのregの各フィールドの拡張
         X  |         1 | SIB のindex フィールドの拡張
         R  |         2 | ModRM のreg フィールドの拡張
         W  |         3 | 0 = デフォルトのオペランドサイズ、1 = 64 ビットのオペランド・サイズ

ModR/M (Mode Register Memory)

ModR/Mはオペコードの直後においてレジスタとアドレッシングモードを指定するための1バイトのデータ。

bit   |0|1|2|3|4|5|6|7|
-----------------------
field | r/m | reg |mod|
-----------------------
rex   |  b  |  r  |   |
  • reg

オペランドのレジスタを指定する3ビットのフィールド。R8からR15のレジスタを指定する場合は、REXプレフィックスのRフィールドの指定が必要。

reg レジスタ (rex.r = 0) レジスタ (rex.r = 1)
000 RAX R8
001 RCX R9
010 RDX R10
011 RBX R11
100 RSP R12
101 RBP R13
110 RSI R14
111 RDI R15
  • modとr/m

modフィールドの2ビット、r/mフィールドの3ビット、REXプレフィックスのBフィールドの1ビットの合計6ビットを用いて、64種類のアドレッシングモードの指定を行う。

modが11の場合は直悦レジスタを指定することを意味し、転送や計算の対象がレジスタとある。modがそれ以外の場合は、指定されたメモリアドレスが格納しチエルデータが転送や計算の対象となる。

x86-64では、RIP相対アドレッシングによって、次ん尾命令を示すプログラムカウンタとの相対値でアドレスを指定することが、ModR/Mを使うすべての命令で可能になっている。データ位置をこのようなRIP相対アドレッシングで指定した場合、メモリ中のどこにプログラムを配置してもプログラム自身を圓光する必要が生じない。

mod
00 01 10 11
000 [RAX] [RAX + disp8] [RAX + disp32] RAX
001 [RCX] [RCX + disp8] [RCX + disp32] RCX
010 [RDX] [RDX + disp8] [RDX + disp32] RDX
r/m (rex.b = 0) 011 [RBX] [RBX + disp8] [RBX + disp32] RBX
100 [SIB] [SIB + disp8] [SIB + disp32] RSP
101 [RIP + disp32] [RBP + disp8] [RBP+ disp32] RBP
110 [RSI] [RSI + disp8] [RSI + disp32] RSI
111 [RDI] [RDI + disp8] [RDI + disp32] RDI
mod
00 01 10 11
000 [R8] [R8 + disp8] [R8 + disp32] R8
001 [R9] [R9 + disp8] [R9+ disp32] R9
010 [R10] [R10 + disp8] [R10 + disp32] R10
r/m (rex.b = 1) 011 [R11] [R11 + disp8] [R11 + disp32] R11
100 [SIB] [SIB + disp8] [SIB + disp32] R12
101 [RIP + disp32] [R13 + disp8] [R13+ disp32] R13
110 [R14] [R14 + disp8] [R14 + disp32] R14
111 [R15] [R15 + disp8] [R15 + disp32] R15

SIB (Scale Index Base) バイト

MODR/MバイトがSIBを指定している場合は、ベースレジスタ + インデックスレジスタ * スケール + 定数の形式でメモリアドレスを指定することができる。ベースレジスタとインデックスレジスタは全ての汎用レジスタを指定できる。スケールは1, 2, 4もしくは8を指定可能。

これにより、ベースレジスタに配列の先頭アドレス、インデックスレジスタに配列のインデックス、スケールに書く配列要素のサイズを設定すると、配列の要素へのアクセス (読み出し、書き出し、演算)を1命令で実行できる。

| bit  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|------|---|---|---|---|---|---|---|---|
| field|   base    |   index   | scale |
|------|-----------|-----------|-------|
| rex  |   b       |   x       |       |
  • base

baseはベースレジスタを3bitのフィールドで指定する。拡張汎用レジスタであるR8-R15はREXプレフィックスのBフィールドによって指定できる。

base (reb.b = 0) mod レジスタ
000 RAX
001 RCX
010 RDX
011 RBX
100 RSP
101 00 disp32
101 01 RBP + disp8
101 10 RBP + disp32
110 RSI
111 RDI
base (reb.b = 1) mod レジスタ
000 R8
001 R9
010 R10
011 R11
100 R12
101 00 disp32
101 01 R13 + disp8
101 10 R13 + disp32
110 R14
111 R15
  • index

indexは、インデックスレジスタを指定する3bitのフィールド。拡張汎用レジスタであるR8-R15はREXプレフィックスのXフィールドによって指定できる。

index (rex.x = 0) レジスタ
000 RAX
001 RCX
010 RDX
011 RBX
100 RSP
101 RBP
110 RSI
111 RDI
index (rex.x = 1) レジスタ
000 R8
001 R9
010 R10
011 R11
100 R12
101 R13
110 R14
111 R15
  • scale

インデックスレジスタの倍率を指定する。

scale 倍率
00 なし
01 2
10 4
11 8

各命令の概要

データ転送命令

ニーモニック 命令の動作
MOV データ転送
CBW / CWDE / CDQE rAX レジスタを2倍のビット数に符号拡張
CWD / CDQ / CQO rAX レジスタを rDX:rAX レジスタに符号拡張
MOVSX 符号拡張と転送
MOVZX ゼロ拡張と転送
LEA 実効アドレスのレジスタへのロード
BSWAP エンディアン変更
XCHG データ交換
NOP 何もしない
  • MOV
プリフィックス オペコード 命令 説明
- 88/r MOV r/m8, r8 r8 を r/m8 にコピー
REX        MOV r/m8, r8 r8 を r/m8 にコピー。
66 89/r MOV r/m16, r16 r16 を r/m16 にコピー
- MOV r/m32, r32 r32 を r/m32 にコピー
REX.W MOV r/m64, r64 r64 を r/m64 にコピー
- 8A/r MOV r8, r/m8 r/m8 を r8 にコピー
REX MOV r8, r/m8 r/m8 を r8 にコピー。
66 8B/r MOV r16, r/m16 r/m16 を r16 にコピー
- MOV r32, r/m32 r/m32 を r32 にコピー
REX.W MOV r64, r/m64 r/m64 を r64 にコピー
- 8C/r MOV r/m16, Sreg セグメントレジスタを r/m16 にコピー
REX.W MOV r/m64, Sreg ゼロ拡張された16ビットのセグメントレジスタを r/m64 にコピー
- 8E/r MOV Sreg, r/m16 r/m16 をセグメントレジスタにコピー
REX.W MOV Sreg, r/m64 r/m64 の下位16ビットをセグメントレジスタにコピー
- A0 MOV AL, moffs8 (セグメント:オフセット) のバイトを AL にコピー
REX.W MOV AL, moffs8 (オフセット) のバイトを AL にコピー
66 A1 MOV AX, moffs16 (セグメント:オフセット) のワードを AX にコピー
- MOV EAX, moffs32 (セグメント:オフセット) のダブルワードを EAX にコピー
REX.W MOV RAX, moffs64 (オフセット) のクワッドワードを RAX にコピー
- A2 MOV moffs8, AL AL を(セグメント:オフセット) にコピー
REX.W MOV moffs8, AL AL を(オフセット) にコピー
- A3 MOV moffs16, AX AX を(セグメント:オフセット) にコピー
REX.W MOV moffs64, RAX RAX を(オフセット) にコピー
- B0+rb MOV r8, imm8 8ビット定数 を r8 にコピー
REX MOV r8, imm8 8ビット定数 を r8 にコピー。
66 B8+rw MOV r16, imm16 16ビット定数 を r16 にコピー
- B8+rd MOV r32, imm32 32ビット定数 を r32 にコピー
REX.W MOV r64, imm64 64ビット定数 を r64 にコピー
- C6/0 MOV r/m8, imm8 8ビット定数 を r/m8 にコピー
REX MOV r/m8, imm8 8ビット定数 を r/m8 にコピー。
66 C7/0 MOV r/m16, imm16 16ビット定数 を r/m16 にコピー
- MOV r/m32, imm32 32ビット定数 を r/m32 にコピー
REX.W MOV r/m64, imm32 64ビットにゼロ拡張された 32ビット定数 を r/m64 にコピー

演算命令

ニーモニック 命令の動作
ADD 整数加算
ADC キャリーを含む整数加算
SUB 整数減算
SBB キャリー(ボロー)を含む整数減算
INC 1 の加算
DEC 1 の減算
NEG 2の補数(正負の反転)
AND ビット毎の論理積
OR ビット毎の論理和
XOR ビット毎の排他的論理和
NOT ビットの反転(1の補数)
MUL 符号無し整数乗算
IMUL 符号付き数の整数乗算
DIV 符号無し整数除算
IDIV 符号付き数の整数除算
CMP 減算による比較
TEST ビット毎の論理積による比較

シフト/ローテイト命令

ニーモニック 命令の動作
SAR 算術的右シフト
SHR 論理的右シフト
SALSHL 左シフト
SHLD 連結したレジスタを右シフト
SHRD 連結したレジスタを左シフト
ROR 右ローテイト
ROL 左ローテイト
RCR キャリーを含む右ローテイト
RCL キャリーを含む左ローテイト

Useful Resources

Clone this wiki locally