MOVの機械語
MOV AX,BXのようなレジスタ間移動のMOVの機械語は[オペコード] [ModR/M]
(2バイト)からなります。
MOV 命令オペコード一覧(Mod=11 / レジスタ間)
オペコード | オペランド大きさ | 命令形式 | 意味 |
---|---|---|---|
88 /r |
8bit | MOV r/m8, r8 |
レジスタ → レジスタ/メモリ(8bit) |
8A /r |
8bit | MOV r8, r/m8 |
レジスタ/メモリ → レジスタ(8bit) |
89 /r |
16bit | MOV r/m16, r16 |
レジスタ → レジスタ/メモリ(16bit) |
8B /r |
16bit | MOV r16, r/m16 |
レジスタ/メモリ → レジスタ(16bit) |
※オペランドが2つともレジスタの場合、2通りのオペコードが存在します。
例えば8bitの場合は下に載せたMod R/M中のreg及びr/mにどちらのレジスタを入れるかによって88と8Aが入れ替わります。
Mod R/Mの構成
フィールド | ビット幅 | 説明 |
---|---|---|
Mod | 2ビット | レジスタ間操作の場合は 11 固定 |
reg | 3ビット | レジスタを3ビット値で指定 |
r/m | 3ビット | レジスタ若しくはメモリを3ビット値で指定 |
(レジスタのビット値は下の表を参照)
Mod値
Mod値 | 意味 | 例 |
---|---|---|
00 | オフセットなし(※BPは例外) | [BX+SI] |
01 | 8ビットオフセット | [BX+SI+5] |
10 | 16ビットオフセット | [BX+SI+1000] |
11 | レジスタ間移動 | AX ← BX |
今回はレジスタ間移動のみに絞って話を進めるため、Mod=11で固定です。00,01,10は今回使用しません。
レジスタ3ビット値
レジスタ | ビット幅 | 3ビット値 | バイナリ |
---|---|---|---|
AL | 8bit(下位) | 000 | 000 |
CL | 8bit | 001 | 001 |
DL | 8bit | 010 | 010 |
BL | 8bit | 011 | 011 |
AH | 8bit(上位) | 100 | 100 |
CH | 8bit | 101 | 101 |
DH | 8bit | 110 | 110 |
BH | 8bit | 111 | 111 |
実際にNASMが生成した機械語
ubuntu@ubuntu:~/kaihatsu/demo$ nasm -f bin demo.asm -o demo.bin
ubuntu@ubuntu:~/kaihatsu/demo$ ndisasm -b 16 demo.bin
00000000 88D8 mov al,bl
00000002 88C8 mov al,cl
00000004 88D0 mov al,dl
00000006 88C3 mov bl,al
00000008 88CB mov bl,cl
0000000A 88D3 mov bl,dl
0000000C 88C1 mov cl,al
0000000E 88D9 mov cl,bl
00000010 88D1 mov cl,dl
00000012 88FC mov ah,bh
00000014 88EC mov ah,ch
00000016 88F4 mov ah,dh
00000018 88E7 mov bh,ah
0000001A 88EF mov bh,ch
0000001C 88F7 mov bh,dh
0000001E 88E5 mov ch,ah
00000020 88FD mov ch,bh
00000022 88F5 mov ch,dh
mov al,bl
が何故88D8
になるのか
- alもblもレジスタなのでMod=11
- レジスタ→レジスタへの移動なのでオペコードは88(実際には8Aでも良いのですがそれは下の節で説明します)
- 3ビット値 AL=000 BL=011
reg=BL
r/m =AL
よって
11 011 000 となり16進数にするとD8となる。
オペコードが88の場合はMOV r/m8, r8
であり、BLからALへ代入すると解釈する。
[オペコード] [Mod][reg][r/m]
88 11 011 000
| | |
Mod=11 reg=BL r/m=AL
命令意味: MOV r/m8, r8
AL ← BL
mov al,bl
のもう一つの機械語
NASMはオペコードを88として機械語を生成していました。
以下のようにオペコードを8Aにして、regとr/mを逆にすると、8A C3
(AL ← BL)になります。
[オペコード] [Mod][reg][r/m]
8A 11 000 011
| | |
Mod=11 reg=AL r/m=BL
命令意味: MOV r/m8, r8
AL → BL
88D8
と8AC3
が等しいことを証明するためにMS-DOSのdebugのe命令を用いて実際に16進数で88D8
と8AC3
を書き込み、u命令で逆アセンブルしたものが以下の写真になります。
機械語は違いますがどちらもmov al,blとなっています。
NASM