付録A 登場した機械語命令と構文の一覧
A.1 構文表記のキーワードについて
本文でも説明した通り、機械語の構文には、オフセットを足すことで対象のレジスタやアドレス等、細かい意味が変わる構文があります。
本書では、そのようなオフセットはキーワードを対応付けて、構文を表現しています。
ここでは、本書で登場したキーワードをまとめます。
rel_addr
ジャンプ命令で使用するキーワードで、自身の命令の地点からのジャンプ先の相対的なバイト数を示します。
reg_ofs
対象のレジスタを示すオフセット値です。
| reg_ofs | 64bit | 32bit | 16bit | 8bit |
| 0 | RAX | EAX | AX | AL |
| 1 | RCX | ECX | CX | CL |
| 2 | RDX | EDX | DX | DL |
| 3 | RBX | EBX | BX | BL |
| 4 | RSP | ESP | SP | AH |
| 5 | RBP | EBP | BP | CH |
| 6 | RSI | ESI | SI | DH |
| 7 | RDI | EDI | DI | BH |
reg_src_dst
オペランドにレジスタが複数登場する場合、元(src)と先(dst)のレジスタの組み合わせを示すオフセット値です。
8ビットレジスタ同士の場合
| src/dst | AL | CL | DL | BL | AH | CH | DH | BH |
| AL | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| CL | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| DL | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| BL | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| AH | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| CH | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| DH | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| BH | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
32ビットレジスタ同士の場合
| src/dst | EAX | ECX | EDX | EBX | ESP | EBP | ESI | EDI |
| EAX | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| ECX | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| EDX | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| EBX | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| ESP | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| EBP | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| ESI | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| EDI | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
32ビットレジスタと64ビットレジスタ間接の場合
| src/(dst) | (RAX) | (RCX) | (RDX) | (RBX) | (RSP) | (RBP) | (RSI) | (RDI) |
| EAX | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| ECX | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| EDX | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| EBX | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| ESP | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| EBP | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| ESI | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| EDI | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
reg_dst_src
こちらも、元(src)と先(dst)のレジスタの組み合わせを示すオフセット値で、オフセット値を増やしていった際のsrcとdstの関係が「reg_dst_src」とは異なるパターンです。
端的には、オフセット値を行方向に増やしていく表記をする際、「reg_dst_src」は、列がdst、行がsrcになります。
16ビットレジスタ同士の場合
| dst/src | AX | CX | DX | BX | SP | BP | SI | DI |
| AX | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| CX | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| DX | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| BX | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| SP | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| BP | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| SI | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| DI | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
32ビットレジスタ同士の場合
| dst/src | EAX | ECX | EDX | EBX | ESP | EBP | ESI | EDI |
| EAX | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| ECX | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| EDX | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| EBX | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| ESP | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| EBP | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| ESI | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| EDI | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
32ビットレジスタと64ビットレジスタ間接の場合
| dst/(src) | (RAX) | (RCX) | (RDX) | (RBX) | (RSP) | (RBP) | (RSI) | (RDI) |
| EAX | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| ECX | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| EDX | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| EBX | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| ESP | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| EBP | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| ESI | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| EDI | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
64ビットレジスタと64ビットレジスタ間接の場合
| dst/(src) | (RAX) | (RCX) | (RDX) | (RBX) | (RSP) | (RBP) | (RSI) | (RDI) |
| RAX | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
| RCX | 0x08 | 0x09 | 0x0a | 0x0b | 0x0c | 0x0d | 0x0e | 0x0f |
| RDX | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
| RBX | 0x18 | 0x19 | 0x1a | 0x1b | 0x1c | 0x1d | 0x1e | 0x1f |
| RSP | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
| RBP | 0x28 | 0x29 | 0x2a | 0x2b | 0x2c | 0x2d | 0x2e | 0x2f |
| RSI | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
| RDI | 0x38 | 0x39 | 0x3a | 0x3b | 0x3c | 0x3d | 0x3e | 0x3f |
A.2 四則演算
add: 加算
| 構文6 | add: 即値(8bit)をALへ加算 |
| アセンブラ | add 即値(8bit), %al |
| 機械語 | 04 即値(8bit) |
| |
| 構文7 | add: 即値(8bit)をレジスタ(8bit)へ加算 |
| アセンブラ | add 即値(8bit), レジスタ(8bit) |
| 機械語 | 80 c0+reg_ofs 即値(8bit) |
| |
| 構文42 | add: 即値(8bit)をレジスタ(64bit)へ加算 |
| アセンブラ | add 即値(8bit), レジスタ(64bit) |
| 機械語 | 48 83 c0+reg_ofs 即値(8bit) |
sub: 減算
| 構文8 | sub: 即値(8bit)をALレジスタから減算 |
| アセンブラ | sub 即値(8bit), %al |
| 機械語 | 2c 即値(8bit) |
| |
| 構文9 | sub: 即値(8bit)をレジスタ(8bit)から減算 |
| アセンブラ | sub 即値(8bit), レジスタ(8bit) |
| 機械語 | 80 e8+reg_ofs 即値(8bit) |
imul: 乗算
| 構文10 | imul: AL * レジスタ(8bit)をAXへ格納 |
| アセンブラ | imul レジスタ(8bit) |
| 機械語 | f6 e8+reg_ofs |
| |
| 構文11 | imul: 第1 * 第2オペランド(16bitレジスタ)を第2オペランドへ格納 |
| アセンブラ | imul レジスタ(16bit,src), レジスタ(16bit,dst) |
| 機械語 | 66 0f af c0+reg_dst_src |
| |
| 構文12 | imul: 第1オペランド * 第2オペランドを第3オペランドへ格納 |
| アセンブラ | imul 即値(8bit), レジスタ(16bit,src), レジスタ(16bit,dst) |
| 機械語 | 66 6b c0+reg_dst_src 即値(8bit) |
| |
| 構文40 | imul: レジスタ(32bit)同士の積を第2オペランドへ格納 |
| アセンブラ | imul レジスタ(32bit), レジスタ(32bit) |
| 機械語 | 0f af c0+reg_dst_src |
idiv: 除算
| 構文13 | idiv: AX/レジスタ(8bit)の商をALへ剰余をAHへ格納 |
| アセンブラ | idiv レジスタ |
| 機械語 | f6 f8+reg_ofs |
A.3 インクリメント/デクリメント
inc: インクリメント
| 構文24 | inc: レジスタ(8bit)をインクリメント |
| アセンブラ | inc レジスタ(8bit) |
| 機械語 | fe c0+reg_ofs |
| |
| 構文43 | inc: レジスタ(32bit)をインクリメント |
| アセンブラ | inc レジスタ(32bit) |
| 機械語 | ff c0+reg_ofs |
dec: デクリメント
| 構文25 | dec: レジスタ(8bit)をデクリメント |
| アセンブラ | inc レジスタ(32bit) |
| 機械語 | ff c0+reg_ofs |
A.4 比較
cmp: 2つのオペランドの差を評価
| 構文32 | cmp: 即値(8bit)とALを比較 |
| アセンブラ | cmp 即値(8bit), %al |
| 機械語 | 3c 即値(8bit) |
| |
| 構文33 | cmp: 即値(8bit)とレジスタ(8bit)を比較 |
| アセンブラ | cmp 即値(8bit), レジスタ(8bit) |
| 機械語 | 80 f8+reg_ofs 即値(8bit) |
| |
| 構文41 | cmp: レジスタ(32bit)同士の比較 |
| アセンブラ | cmp レジスタ(32bit), レジスタ(32bit) |
| 機械語 | 39 c0+reg_src_dst |
A.5 論理演算
and: 論理積
| 構文14 | and: 即値(8bit) AND ALをALへ格納 |
| アセンブラ | and 即値(8bit), %al |
| 機械語 | 24 即値(8bit) |
| |
| 構文15 | and: 即値(8bit) AND レジスタ(8bit)をレジスタ(8bit)へ格納 |
| アセンブラ | and 即値(8bit), レジスタ(8bit) |
| 機械語 | 80 e0+reg_ofs 即値(8bit) |
or: 論理和
| 構文16 | or: 即値(8bit) OR ALをALへ格納 |
| アセンブラ | or 即値(8bit), %al |
| 機械語 | 0c 即値(8bit) |
| |
| 構文17 | or: 即値(8bit) OR レジスタ(8bit)をレジスタ(8bit)へ格納 |
| アセンブラ | or 即値(8bit), レジスタ(8bit) |
| 機械語 | 80 c8+reg_ofs 即値(8bit) |
xor: 排他的論理和
| 構文18 | xor: 即値(8bit) XOR ALをALへ格納 |
| アセンブラ | xor 即値(8bit), %al |
| 機械語 | 34 即値(8bit) |
| |
| 構文19 | xor: 即値(8bit) XOR レジスタ(8bit)をレジスタ(8bit)へ格納 |
| アセンブラ | xor 即値(8bit), レジスタ(8bit) |
| 機械語 | 80 f0+reg_ofs 即値(8bit) |
| |
| 構文38 | xor: レジスタ(32bit)同士のXORを第2オペランドへ格納 |
| アセンブラ | xor レジスタ(32bit), レジスタ(32bit) |
| 機械語 | 31 c0+reg_src_dst |
not: 否定
| 構文20 | not: レジスタ(8bit)のNOTをレジスタ(8bit)へ格納 |
| アセンブラ | not レジスタ(8bit) |
| 機械語 | f6 d0+reg_ofs |
A.6 ビットシフト
ビットシフトは挙動としては表A.20の通りです。
表A.20: 各シフト演算の挙動
| sal | 第1オペランドの回数分、第2オペランドへ2を掛ける |
| sar | 第1オペランドの回数分、第2オペランドを2で割る(符号有) |
| shl | 第1オペランドの回数分、第2オペランドへ2を掛ける |
| shr | 第1オペランドの回数分、第2オペランドを2で割る(符号無) |
salとshlは挙動が同じなので、機械語も同じです。そのため、salのみ紹介します。
sal: 算術左シフト
| 構文21 | sal: 第1オペランド=即値(8bit)、第2オペランド=レジスタ(8bit) |
| アセンブラ | sal 即値(8bit), レジスタ(8bit) |
| 機械語 | c0 e0+reg_ofs 即値(8bit) |
sar: 算術右シフト
| 構文22 | sar: 第1オペランド=即値(8bit)、第2オペランド=レジスタ(8bit) |
| アセンブラ | sar 即値(8bit), レジスタ(8bit) |
| 機械語 | c0 f8+reg_ofs 即値(8bit) |
shr: 論理右シフト
| 構文23 | shr: 第1オペランド=即値(8bit)、第2オペランド=レジスタ(8bit) |
| アセンブラ | shr 即値(8bit), レジスタ(8bit) |
| 機械語 | c0 e8+reg_ofs 即値(8bit) |
A.7 読み出し/書き込み
mov: 第1から第2オペランドへコピー
| 構文4 | mov: 即値(8bit)をレジスタ(8bit)へ格納 |
| アセンブラ | mov 即値(8bit), レジスタ(8bit) |
| 機械語 | b0+reg_ofs 即値(8bit) |
| |
| 構文31 | mov: 第1から第2オペランドへコピー(共に8ビットレジスタ) |
| アセンブラ | mov レジスタ(8bit,src), レジスタ(8bit,dst) |
| 機械語 | 88 c0+reg_src_dst |
| 構文5 | mov: 即値(16bit)をレジスタ(16bit)へ格納 |
| アセンブラ | mov 即値(16bit), レジスタ(16bit) |
| 機械語 | 66 b9+reg_ofs 即値(16bit) |
| 構文39 | mov: 第1から第2オペランドへコピー(共に32bitレジスタ) |
| アセンブラ | mov レジスタ(32bit), レジスタ(32bit) |
| 機械語 | 89 c0+reg_src_dst |
| |
| 構文36 | mov: 即値(32bit)をレジスタ間接で書き込む |
| アセンブラ | movl 即値(32bit), (レジスタ(64bit)) |
| 機械語 | c7 00+reg_ofs 即値(32bit) |
| 備考 | レジスタ間接がRSPの場合、3バイト目に0x24追加 |
| レジスタ間接がRBPの場合、2バイト目に0x40加算、3バイト目に0x00追加 |
| |
| 構文45 | mov: レジスタ(32bit)をレジスタ間接で書き込む |
| アセンブラ | mov レジスタ(32bit), (レジスタ(64bit)) |
| 機械語 | 89 00+reg_src_dst |
| 備考 | レジスタ間接がRSPの場合、3バイト目に0x24追加 |
| レジスタ間接がRBPの場合、2バイト目に0x40加算、末尾に0x00追加 |
| |
| 構文35 | mov: DSP(8bit)付きレジスタ間接の値をレジスタ(32bit)へ格納 |
| アセンブラ | mov dsp(レジスタ(64bit)), レジスタ(32bit) |
| 機械語 | 8b 40+reg_dst_src dsp(8bit) |
| 備考 | レジスタ間接がRSPの場合、3バイト目に0x24追加 |
| 構文34 | mov: 第1オペランドの指す先を第2オペランド(64ビットレジスタ)へ格納 |
| アセンブラ | mov (レジスタ(64bit)), レジスタ(64bit) |
| 機械語 | 48 8b 00+reg_dst_src |
| 備考 | レジスタ間接がRSPの場合、末尾に0x24追加 |
| レジスタ間接がRBPの場合、3バイト目に0x40加算、末尾に0x00追加 |
in: IOアドレス空間から読み出し
| 構文46 | in: IOアドレス(1バイト)先からALへ値を読み出す |
| アセンブラ | in 即値(8bit), %al |
| 機械語 | e4 即値(8bit) |
| |
| 構文27 | in: DXが指すレジスタ値をALへ格納 |
| アセンブラ | in %dx, %al |
| 機械語 | ec |
out: IOアドレス空間へ書き込み
| 構文26 | out: ALをDXが指すアドレス先へ書き込む |
| アセンブラ | out %al, %dx |
| 機械語 | ee |
A.8 CPU状態制御
hlt: CPUをスリープ
| 構文3 | hlt: CPUをスリープさせる |
| アセンブラ | hlt |
| 機械語 | f4 |
pause: ビジーループのヒント
| 構文30 | pause: ビジーループのヒントをCPUへ伝える |
| アセンブラ | pause |
| 機械語 | f3 90 |
A.9 分岐
jmp: 無条件ジャンプ
| 構文1 | jmp: 相対アドレス指定でジャンプ |
| アセンブラ | jmp <ラベルあるいは"."> |
| 機械語 | eb fe+rel_addr |
jb: 小さい(Below)場合にジャンプ
| 構文47 | jb: 比較結果が小さいならジャンプ |
| アセンブラ | jb <ラベルあるいは"."> |
| 機械語 | 72 fe+rel_addr |
jbe: 小さいか等しい(Below or Equal)場合にジャンプ
| 構文37 | jbe: 等しいか小さければジャンプ |
| アセンブラ | jbe <ラベルあるいは"."> |
| 機械語コード | 76 fe+rel_addr |
je: 等しい(Equal)場合にジャンプ
| 構文28 | je: ゼロフラグがセットされていればジャンプ |
| アセンブラ | je <ラベルあるいは"."> |
| 機械語 | 74 fe+rel_addr |
jne: 等しくない(Not Equal)場合にジャンプ
| 構文29 | jne: ゼロフラグがセットされていなければジャンプ |
| アセンブラ | jne <ラベルあるいは"."> |
| 機械語 | 75 fe+rel_addr |
A.10 その他
nop: 何もしない(No Operation)
| 構文2 | nop: 何もしない |
| アセンブラ | nop |
| 機械語 | 90 |
rdrand: 乱数取得
| 構文44 | rdrand: 乱数をレジスタ(32bit)へ格納 |
| アセンブラ | rdrand レジスタ(32bit) |
| 機械語 | 0f c7 f0+reg_ofs |