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 |