付録A 登場した機械語命令と構文の一覧

A.1 構文表記のキーワードについて

本文でも説明した通り、機械語の構文には、オフセットを足すことで対象のレジスタやアドレス等、細かい意味が変わる構文があります。

本書では、そのようなオフセットはキーワードを対応付けて、構文を表現しています。

ここでは、本書で登場したキーワードをまとめます。

rel_addr

ジャンプ命令で使用するキーワードで、自身の命令の地点からのジャンプ先の相対的なバイト数を示します。

reg_ofs

対象のレジスタを示すオフセット値です。

reg_ofs64bit32bit16bit8bit
0RAXEAXAXAL
1RCXECXCXCL
2RDXEDXDXDL
3RBXEBXBXBL
4RSPESPSPAH
5RBPEBPBPCH
6RSIESISIDH
7RDIEDIDIBH

reg_src_dst

オペランドにレジスタが複数登場する場合、元(src)と先(dst)のレジスタの組み合わせを示すオフセット値です。

8ビットレジスタ同士の場合

src/dstALCLDLBLAHCHDHBH
AL0x000x010x020x030x040x050x060x07
CL0x080x090x0a0x0b0x0c0x0d0x0e0x0f
DL0x100x110x120x130x140x150x160x17
BL0x180x190x1a0x1b0x1c0x1d0x1e0x1f
AH0x200x210x220x230x240x250x260x27
CH0x280x290x2a0x2b0x2c0x2d0x2e0x2f
DH0x300x310x320x330x340x350x360x37
BH0x380x390x3a0x3b0x3c0x3d0x3e0x3f

32ビットレジスタ同士の場合

src/dstEAXECXEDXEBXESPEBPESIEDI
EAX0x000x010x020x030x040x050x060x07
ECX0x080x090x0a0x0b0x0c0x0d0x0e0x0f
EDX0x100x110x120x130x140x150x160x17
EBX0x180x190x1a0x1b0x1c0x1d0x1e0x1f
ESP0x200x210x220x230x240x250x260x27
EBP0x280x290x2a0x2b0x2c0x2d0x2e0x2f
ESI0x300x310x320x330x340x350x360x37
EDI0x380x390x3a0x3b0x3c0x3d0x3e0x3f

32ビットレジスタと64ビットレジスタ間接の場合

src/(dst)(RAX)(RCX)(RDX)(RBX)(RSP)(RBP)(RSI)(RDI)
EAX0x000x010x020x030x040x050x060x07
ECX0x080x090x0a0x0b0x0c0x0d0x0e0x0f
EDX0x100x110x120x130x140x150x160x17
EBX0x180x190x1a0x1b0x1c0x1d0x1e0x1f
ESP0x200x210x220x230x240x250x260x27
EBP0x280x290x2a0x2b0x2c0x2d0x2e0x2f
ESI0x300x310x320x330x340x350x360x37
EDI0x380x390x3a0x3b0x3c0x3d0x3e0x3f

reg_dst_src

こちらも、元(src)と先(dst)のレジスタの組み合わせを示すオフセット値で、オフセット値を増やしていった際のsrcとdstの関係が「reg_dst_src」とは異なるパターンです。

端的には、オフセット値を行方向に増やしていく表記をする際、「reg_dst_src」は、列がdst、行がsrcになります。

16ビットレジスタ同士の場合

dst/srcAXCXDXBXSPBPSIDI
AX0x000x010x020x030x040x050x060x07
CX0x080x090x0a0x0b0x0c0x0d0x0e0x0f
DX0x100x110x120x130x140x150x160x17
BX0x180x190x1a0x1b0x1c0x1d0x1e0x1f
SP0x200x210x220x230x240x250x260x27
BP0x280x290x2a0x2b0x2c0x2d0x2e0x2f
SI0x300x310x320x330x340x350x360x37
DI0x380x390x3a0x3b0x3c0x3d0x3e0x3f

32ビットレジスタ同士の場合

dst/srcEAXECXEDXEBXESPEBPESIEDI
EAX0x000x010x020x030x040x050x060x07
ECX0x080x090x0a0x0b0x0c0x0d0x0e0x0f
EDX0x100x110x120x130x140x150x160x17
EBX0x180x190x1a0x1b0x1c0x1d0x1e0x1f
ESP0x200x210x220x230x240x250x260x27
EBP0x280x290x2a0x2b0x2c0x2d0x2e0x2f
ESI0x300x310x320x330x340x350x360x37
EDI0x380x390x3a0x3b0x3c0x3d0x3e0x3f

32ビットレジスタと64ビットレジスタ間接の場合

dst/(src)(RAX)(RCX)(RDX)(RBX)(RSP)(RBP)(RSI)(RDI)
EAX0x000x010x020x030x040x050x060x07
ECX0x080x090x0a0x0b0x0c0x0d0x0e0x0f
EDX0x100x110x120x130x140x150x160x17
EBX0x180x190x1a0x1b0x1c0x1d0x1e0x1f
ESP0x200x210x220x230x240x250x260x27
EBP0x280x290x2a0x2b0x2c0x2d0x2e0x2f
ESI0x300x310x320x330x340x350x360x37
EDI0x380x390x3a0x3b0x3c0x3d0x3e0x3f

64ビットレジスタと64ビットレジスタ間接の場合

dst/(src)(RAX)(RCX)(RDX)(RBX)(RSP)(RBP)(RSI)(RDI)
RAX0x000x010x020x030x040x050x060x07
RCX0x080x090x0a0x0b0x0c0x0d0x0e0x0f
RDX0x100x110x120x130x140x150x160x17
RBX0x180x190x1a0x1b0x1c0x1d0x1e0x1f
RSP0x200x210x220x230x240x250x260x27
RBP0x280x290x2a0x2b0x2c0x2d0x2e0x2f
RSI0x300x310x320x330x340x350x360x37
RDI0x380x390x3a0x3b0x3c0x3d0x3e0x3f

A.2 四則演算

add: 加算

構文6add: 即値(8bit)をALへ加算
アセンブラadd 即値(8bit), %al
機械語04 即値(8bit)
構文7add: 即値(8bit)をレジスタ(8bit)へ加算
アセンブラadd 即値(8bit), レジスタ(8bit)
機械語80 c0+reg_ofs 即値(8bit)
構文42add: 即値(8bit)をレジスタ(64bit)へ加算
アセンブラadd 即値(8bit), レジスタ(64bit)
機械語48 83 c0+reg_ofs 即値(8bit)

sub: 減算

構文8sub: 即値(8bit)をALレジスタから減算
アセンブラsub 即値(8bit), %al
機械語2c 即値(8bit)
構文9sub: 即値(8bit)をレジスタ(8bit)から減算
アセンブラsub 即値(8bit), レジスタ(8bit)
機械語80 e8+reg_ofs 即値(8bit)

imul: 乗算

構文10imul: AL * レジスタ(8bit)をAXへ格納
アセンブラimul レジスタ(8bit)
機械語f6 e8+reg_ofs
構文11imul: 第1 * 第2オペランド(16bitレジスタ)を第2オペランドへ格納
アセンブラimul レジスタ(16bit,src), レジスタ(16bit,dst)
機械語66 0f af c0+reg_dst_src
構文12imul: 第1オペランド * 第2オペランドを第3オペランドへ格納
アセンブラimul 即値(8bit), レジスタ(16bit,src), レジスタ(16bit,dst)
機械語66 6b c0+reg_dst_src 即値(8bit)
構文40imul: レジスタ(32bit)同士の積を第2オペランドへ格納
アセンブラimul レジスタ(32bit), レジスタ(32bit)
機械語0f af c0+reg_dst_src

idiv: 除算

構文13idiv: AX/レジスタ(8bit)の商をALへ剰余をAHへ格納
アセンブラidiv レジスタ
機械語f6 f8+reg_ofs

A.3 インクリメント/デクリメント

inc: インクリメント

構文24inc: レジスタ(8bit)をインクリメント
アセンブラinc レジスタ(8bit)
機械語fe c0+reg_ofs
構文43inc: レジスタ(32bit)をインクリメント
アセンブラinc レジスタ(32bit)
機械語ff c0+reg_ofs

dec: デクリメント

構文25dec: レジスタ(8bit)をデクリメント
アセンブラinc レジスタ(32bit)
機械語ff c0+reg_ofs

A.4 比較

cmp: 2つのオペランドの差を評価

構文32cmp: 即値(8bit)とALを比較
アセンブラcmp 即値(8bit), %al
機械語3c 即値(8bit)
構文33cmp: 即値(8bit)とレジスタ(8bit)を比較
アセンブラcmp 即値(8bit), レジスタ(8bit)
機械語80 f8+reg_ofs 即値(8bit)
構文41cmp: レジスタ(32bit)同士の比較
アセンブラcmp レジスタ(32bit), レジスタ(32bit)
機械語39 c0+reg_src_dst

A.5 論理演算

and: 論理積

構文14and: 即値(8bit) AND ALをALへ格納
アセンブラand 即値(8bit), %al
機械語24 即値(8bit)
構文15and: 即値(8bit) AND レジスタ(8bit)をレジスタ(8bit)へ格納
アセンブラand 即値(8bit), レジスタ(8bit)
機械語80 e0+reg_ofs 即値(8bit)

or: 論理和

構文16or: 即値(8bit) OR ALをALへ格納
アセンブラor 即値(8bit), %al
機械語0c 即値(8bit)
構文17or: 即値(8bit) OR レジスタ(8bit)をレジスタ(8bit)へ格納
アセンブラor 即値(8bit), レジスタ(8bit)
機械語80 c8+reg_ofs 即値(8bit)

xor: 排他的論理和

構文18xor: 即値(8bit) XOR ALをALへ格納
アセンブラxor 即値(8bit), %al
機械語34 即値(8bit)
構文19xor: 即値(8bit) XOR レジスタ(8bit)をレジスタ(8bit)へ格納
アセンブラxor 即値(8bit), レジスタ(8bit)
機械語80 f0+reg_ofs 即値(8bit)
構文38xor: レジスタ(32bit)同士のXORを第2オペランドへ格納
アセンブラxor レジスタ(32bit), レジスタ(32bit)
機械語31 c0+reg_src_dst

not: 否定

構文20not: レジスタ(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: 算術左シフト

構文21sal: 第1オペランド=即値(8bit)、第2オペランド=レジスタ(8bit)
アセンブラsal 即値(8bit), レジスタ(8bit)
機械語c0 e0+reg_ofs 即値(8bit)

sar: 算術右シフト

構文22sar: 第1オペランド=即値(8bit)、第2オペランド=レジスタ(8bit)
アセンブラsar 即値(8bit), レジスタ(8bit)
機械語c0 f8+reg_ofs 即値(8bit)

shr: 論理右シフト

構文23shr: 第1オペランド=即値(8bit)、第2オペランド=レジスタ(8bit)
アセンブラshr 即値(8bit), レジスタ(8bit)
機械語c0 e8+reg_ofs 即値(8bit)

A.7 読み出し/書き込み

mov: 第1から第2オペランドへコピー

構文4mov: 即値(8bit)をレジスタ(8bit)へ格納
アセンブラmov 即値(8bit), レジスタ(8bit)
機械語b0+reg_ofs 即値(8bit)
構文31mov: 第1から第2オペランドへコピー(共に8ビットレジスタ)
アセンブラmov レジスタ(8bit,src), レジスタ(8bit,dst)
機械語88 c0+reg_src_dst
構文5mov: 即値(16bit)をレジスタ(16bit)へ格納
アセンブラmov 即値(16bit), レジスタ(16bit)
機械語66 b9+reg_ofs 即値(16bit)
構文39mov: 第1から第2オペランドへコピー(共に32bitレジスタ)
アセンブラmov レジスタ(32bit), レジスタ(32bit)
機械語89 c0+reg_src_dst
構文36mov: 即値(32bit)をレジスタ間接で書き込む
アセンブラmovl 即値(32bit), (レジスタ(64bit))
機械語c7 00+reg_ofs 即値(32bit)
備考レジスタ間接がRSPの場合、3バイト目に0x24追加
レジスタ間接がRBPの場合、2バイト目に0x40加算、3バイト目に0x00追加
構文45mov: レジスタ(32bit)をレジスタ間接で書き込む
アセンブラmov レジスタ(32bit), (レジスタ(64bit))
機械語89 00+reg_src_dst
備考レジスタ間接がRSPの場合、3バイト目に0x24追加
レジスタ間接がRBPの場合、2バイト目に0x40加算、末尾に0x00追加
構文35mov: DSP(8bit)付きレジスタ間接の値をレジスタ(32bit)へ格納
アセンブラmov dsp(レジスタ(64bit)), レジスタ(32bit)
機械語8b 40+reg_dst_src dsp(8bit)
備考レジスタ間接がRSPの場合、3バイト目に0x24追加
構文34mov: 第1オペランドの指す先を第2オペランド(64ビットレジスタ)へ格納
アセンブラmov (レジスタ(64bit)), レジスタ(64bit)
機械語48 8b 00+reg_dst_src
備考レジスタ間接がRSPの場合、末尾に0x24追加
レジスタ間接がRBPの場合、3バイト目に0x40加算、末尾に0x00追加

in: IOアドレス空間から読み出し

構文46in: IOアドレス(1バイト)先からALへ値を読み出す
アセンブラin 即値(8bit), %al
機械語e4 即値(8bit)
構文27in: DXが指すレジスタ値をALへ格納
アセンブラin %dx, %al
機械語ec

out: IOアドレス空間へ書き込み

構文26out: ALをDXが指すアドレス先へ書き込む
アセンブラout %al, %dx
機械語ee

A.8 CPU状態制御

hlt: CPUをスリープ

構文3hlt: CPUをスリープさせる
アセンブラhlt
機械語f4

pause: ビジーループのヒント

構文30pause: ビジーループのヒントをCPUへ伝える
アセンブラpause
機械語f3 90

A.9 分岐

jmp: 無条件ジャンプ

構文1jmp: 相対アドレス指定でジャンプ
アセンブラjmp <ラベルあるいは".">
機械語eb fe+rel_addr

jb: 小さい(Below)場合にジャンプ

構文47jb: 比較結果が小さいならジャンプ
アセンブラjb <ラベルあるいは".">
機械語72 fe+rel_addr

jbe: 小さいか等しい(Below or Equal)場合にジャンプ

構文37jbe: 等しいか小さければジャンプ
アセンブラjbe <ラベルあるいは".">
機械語コード76 fe+rel_addr

je: 等しい(Equal)場合にジャンプ

構文28je: ゼロフラグがセットされていればジャンプ
アセンブラje <ラベルあるいは".">
機械語74 fe+rel_addr

jne: 等しくない(Not Equal)場合にジャンプ

構文29jne: ゼロフラグがセットされていなければジャンプ
アセンブラjne <ラベルあるいは".">
機械語75 fe+rel_addr

A.10 その他

nop: 何もしない(No Operation)

構文2nop: 何もしない
アセンブラnop
機械語90

rdrand: 乱数取得

構文44rdrand: 乱数をレジスタ(32bit)へ格納
アセンブラrdrand レジスタ(32bit)
機械語0f c7 f0+reg_ofs