0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

x86 MOV命令 MOV AL,BLのようなレジスタ間移動の機械語はどう生成される?

Last updated at Posted at 2025-05-28

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になるのか

  1. alもblもレジスタなのでMod=11
  2. レジスタ→レジスタへの移動なのでオペコードは88(実際には8Aでも良いのですがそれは下の節で説明します)
  3. 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

88D88AC3が等しいことを証明するためにMS-DOSのdebugのe命令を用いて実際に16進数で88D88AC3を書き込み、u命令で逆アセンブルしたものが以下の写真になります。
機械語は違いますがどちらもmov al,blとなっています。
8957a6d106953a92159f7e63bd493308.jpeg

NASM

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?