ADD命令(imm+r→r)

ADD命令の即値→レジスタ間転送の逆アセンブル結果です。

   0:	04 7f                	add    $0x7f,%al
   2:	80 c3 7f             	add    $0x7f,%bl
   5:	80 c1 7f             	add    $0x7f,%cl
   8:	80 c2 7f             	add    $0x7f,%dl
   b:	66 05 ff 7f          	add    $0x7fff,%ax
   f:	66 81 c3 ff 7f       	add    $0x7fff,%bx
  14:	66 81 c1 ff 7f       	add    $0x7fff,%cx
  19:	66 81 c2 ff 7f       	add    $0x7fff,%dx
  1e:	05 ff ff ff 7f       	add    $0x7fffffff,%eax
  23:	81 c3 ff ff ff 7f    	add    $0x7fffffff,%ebx
  29:	81 c1 ff ff ff 7f    	add    $0x7fffffff,%ecx
  2f:	81 c2 ff ff ff 7f    	add    $0x7fffffff,%edx

目についた点として、レジスタがAL/AX/EAXの時だけ、命令コードと命令長が他と異なっているようです。実際、Intelのマニュアルを読むと、AL/AX/EAXレジスタの場合のみ、独自のオペコードが割り当てられるようです。さらに、他のレジスタの場合は、ModR/Mフィールドっていうのが存在するようです。

即値→AL/AX/EAXレジスタのADD命令

オペコード 第1オペランド 説明
04 imm8 imm8をALに加算
66 05 imm16 imm16をAXに加算
05 imm32 imm32をEAXに加算

…というように、とっても簡単ですね(^^)。一服の清涼剤のようです。

で、AL/AX/EAXレジスタ以外のレジスタについては、命令フォーマットは…

オペコード ModR/M 第1オペランド 説明
80 11 000 [r/mフィールド] imm8 imm8をr/mに加算
66 81 11 000 [r/mフィールド] imm16 imm16をr/mに加算
81 11 000 [r/mフィールド] imm32 imm32をr/mに加算

…となるのですが、ModR/Mフィールドをオペコードに含めて、16進数で表現してやると、こんな風に見やすくなります。

オペコード 第1オペランド 説明
80 C[r/mフィールド] imm8 imm8をr/mに加算
66 81 C[r/mフィールド] imm16 imm16をr/mに加算
81 C[r/mフィールド] imm32 imm32をr/mに加算

なお、r/mフィールドは、以下3ビットの値で、使用するレジスタを指定します。

レジスタ r/m
CL/CX/ECX 001
DL/DX/EDX 010
BL/BX/EBX 011