-
Notifications
You must be signed in to change notification settings - Fork 0
Home
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
メモリアドレスは、ベースレジスタ + インデックスレジスタ * スケール + 定数
という形式で指定することができる。
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はオペコードの直後においてレジスタとアドレッシングモードを指定するための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 |
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 | キャリーを含む左ローテイト |