MOV命令(imm→r)

MOV命令(即値→レジスタの転送)の、アセンブリコードとニーモニックの対応です。

ニーモニック アセンブリ
b0 7f mov $0x7f,%al
b3 7f mov $0x7f,%bl
b1 7f mov $0x7f,%cl
b2 7f mov $0x7f,%dl
b8 ff ff ff 7f mov $0x7fffffff,%eax
bb ff ff ff 7f mov $0x7fffffff,%ebx
b9 ff ff ff 7f mov $0x7fffffff,%ecx
ba ff ff ff 7f mov $0x7fffffff,%edx
66 b8 ff 7f mov $0x7fff,%ax
66 bb ff 7f mov $0x7fff,%bx
66 b9 ff 7f mov $0x7fff,%cx
66 ba ff 7f mov $0x7fff,%dx

ニーモニックを見ると、「7f」「ff ff ff 7f」「ff 7f」が、即値指定の部分であることが分かります(リトルエンディアンであることに注意)。すると、この即値を除いた残りの部分が、オペコードだなと予測できます。

ニーモニック アセンブリ
b0 [imm8] mov [imm8],%al
b3 [imm8] mov [imm8],%bl
b1 [imm8] mov [imm8],%cl
b2 [imm8] mov [imm8],%dl
b8 [imm32] mov [imm32],%eax
bb [imm32] mov [imm32],%ebx
b9 [imm32] mov [imm32],%ecx
ba [imm32] mov [imm32],%edx
66 b8 [imm16] mov [imm16],%ax
66 bb [imm16] mov [imm16],%bx
66 b9 [imm16] mov [imm16],%cx
66 ba [imm16] mov [imm16],%dx

そうして見ると、AX、BX、CX、DXレジスタへの転送に限り、命令長は4バイトとなっています。これは、オペランドを16ビットで扱う場合、先頭に命令プリフィックスとして「0x66」が付与するためです。

つまり、即値→オペランドのMOV命令のフォーマットは、[オペコード]+[即値]であり、

オペコード 即値 説明
B0+rb imm8 即値(8ビット)をレジスタ(8ビット)に転送する
66 B8+rw imm16 即値(16ビット)をレジスタ(16ビット)に転送する
B8+rd imm32 即値(32ビット)をレジスタ(32ビット)に転送する

+rb、+rw,+rdとありますが、これは、転送先レジスタに応じて、オペコードに以下の値を加算した値が、実際のオペコードになることを意味します。例えば、EBXレジスタに対するMOV命令は、0xB8+3=「0xBB」になります。

rb rw rd
AL = 0 AX = 0 EAX = 0
CL = 1 CX = 1 ECX = 1
DL = 2 DX = 2 EDX = 2
BL = 3 BX = 3 EBX = 3