ADD命令(imm+r→r)
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 |