add [ebx], al
add al, [ebx]
The MOD-REG-R/M byte specifies instruction operands and their addressing mode:
MOD-REG-R/M Byte
The MOD field specifies x86 addressing mode:
MOD Meaning
The REG field specifies source or destination register:
x86 register encoding
The R/M field, combined with MOD, specifies either
the second operand in a two-operand instruction, or
the only operand in a single-operand instruction like NOT or NEG.
The d bit in the opcode determines which operand is the source, and which is the destination:
d=0: MOD R/M <- REG, REG is the source
d=1: REG <- MOD R/M, REG is the destination
Since the processor accesses registers more quickly than it accesses memory, you can make your programs run faster by keeping the most-frequently used data in registers.
For certain (often single-operand or immediate-operand) instructions, the REG field may contain an opcode extension rather than the register bits. The R/M field will specify the operand in such case.
MOD R/M Addressing Mode === === ================================ 00 000 [ eax ] 01 000 [ eax + disp8 ] (1) 10 000 [ eax + disp32 ] 11 000 register ( al / ax / eax ) (2) 00 001 [ ecx ] 01 001 [ ecx + disp8 ] 10 001 [ ecx + disp32 ] 11 001 register ( cl / cx / ecx ) 00 010 [ edx ] 01 010 [ edx + disp8 ] 10 010 [ edx + disp32 ] 11 010 register ( dl / dx / edx ) 00 011 [ ebx ] 01 011 [ ebx + disp8 ] 10 011 [ ebx + disp32 ] 11 011 register ( bl / bx / ebx ) 00 100 SIB Mode (3) 01 100 SIB + disp8 Mode 10 100 SIB + disp32 Mode 11 100 register ( ah / sp / esp ) 00 101 32-bit Displacement-Only Mode (4) 01 101 [ ebp + disp8 ] 10 101 [ ebp + disp32 ] 11 101 register ( ch / bp / ebp ) 00 110 [ esi ] 01 110 [ esi + disp8 ] 10 110 [ esi + disp32 ] 11 110 register ( dh / si / esi ) 00 111 [ edi ] 01 111 [ edi + disp8 ] 10 111 [ edi + disp32 ] 11 111 register ( bh / di / edi )
Addressing modes with 8-bit displacement fall in the range -128..+127 and require only a single byte displacement after the opcode (Faster!)
The size bit in the opcode specifies 8 or 32-bit register size. To select a 16-bit register requires a prefix byte.
The so-called scaled indexed addressing modes, SIB = scaled index byte mode.
Note that there is no [ ebp ] addressing. It's slot is occupied by the 32-bit displacement only addressing mode. Intel decided that programmers can use [ ebp+ disp8 ] addressing mode instead, with its 8-bit displacement set equal to zero (instruction is a little longer, though.)
Scaled indexed addressing mode uses the second byte (namely, SIB byte) that follows the MOD-REG-R/M byte in the instruction format.
The MOD field still specifies the displacement size of zero, one, or four bytes.
The MOD-REG-R/M and SIB bytes are complex, because Intel reused 16-bit addressing circuitry in the 32-bit mode, rather than simply abandoning the 16-bit format in the 32-bit mode.
There are good hardware reasons for this, but the end result is a complex scheme for specifying addressing modes in the opcodes.
Scaled index byte layout:
SIB, Scaled index byte layout
SIB scaled index values
[ reg32 + eax*n ] MOD = 00 [ reg32 + ebx*n ] [ reg32 + ecx*n ] [ reg32 + edx*n ] [ reg32 + ebp*n ] [ reg32 + esi*n ] [ reg32 + edi*n ] [ disp + reg8 + eax*n ] MOD = 01 [ disp + reg8 + ebx*n ] [ disp + reg8 + ecx*n ] [ disp + reg8 + edx*n ] [ disp + reg8 + ebp*n ] [ disp + reg8 + esi*n ] [ disp + reg8 + edi*n ] [ disp + reg32 + eax*n ] MOD = 10 [ disp + reg32 + ebx*n ] [ disp + reg32 + ecx*n ] [ disp + reg32 + edx*n ] [ disp + reg32 + ebp*n ] [ disp + reg32 + esi*n ] [ disp + reg32 + edi*n ] [ disp + eax*n ] MOD = 00, and [ disp + ebx*n ] BASE field = 101 [ disp + ecx*n ] [ disp + edx*n ] [ disp + ebp*n ] [ disp + esi*n ] [ disp + edi*n ]
Note: n = 1, 2, 4, or 8.
In each scaled indexed addressing mode the MOD field in MOD-REG-R/M byte specifies the size of the displacement. It can be zero, one, or four bytes:
MOD R/M Addressing Mode --- --- --------------------------- 00 100 SIB 01 100 SIB + disp8 10 100 SIB + disp32
The Base and Index fields of the SIB byte select the base and index registers, respectively.
Note that this addressing mode does not allow the use of the ESP register as an index register. Presumably, Intel left this particular mode undefined to provide the ability to extend the addressing modes in a future version of the CPU.
add ecx, eax
Encoding ADD ECX, EAX Instruction
add edx, [disp]Encoding the ADD EDX, DISP Instruction
Encoding the ADD EDI, [ EBX ] instruction:
add edi, [ebx] Encoding the ADD EDI, [EBX] Instruction
Encoding the ADD EBX, [ EBP + disp32 ] instruction:
add ebx, [ ebp + disp32 ] Encoding the ADD EBX, [ EBP + disp32 ] Instruction
Encoding the ADD ECX, [ EBX + EDI*4 ] Instruction
add ecx, [ ebx + edi*4 ] Encoding ADD ECX, [ EBX + EDI*4 ] Instruction
MOD-REG-R/M and SIB bytes have no bit combinations to specify an immediate operand.
Instead, x86 uses a entirely different instruction format to specify instruction with an immediate operand.
Encoding x86 immediate operands:
Encoding Immediate Operands
The third difference between the ADD-immediate and the standard ADD instruction is the meaning of the REG field in the MOD-REG-R/M byte:
Note that when adding a constant to a memory location, the displacement (if any) immediately precedes the immediate (constant) value in the opcode sequence.
Instruction set architecture design that can stand the test of time is a true intellectual challenge.
It takes several compromises between space and efficiency to assign opcodes and encode instruction formats.
Today people are using Intel x86 instruction set for purposes never intended by original designers.
Extending the CPU is a very difficult task.
The instruction set can become extremely complex.
If x86 CPU was designed from scratch today, it would have a totally different ISA!
Software developers usually don't have a problem adapting to a new architecture when writing new software...
...but they are very resistant to moving existing software from one platform to another.
This is the primary reason the Intel x86 platform remains so popular to this day.