Why is this written
lea eax, [rdi + rsi]
instead of just lea eax, rdi + rsi
?Why is this written
lea eax, [rdi + rsi]
instead of just lea eax, rdi + rsi
?In `op reg1, reg2`, the two registers are encoded as 3 bits each the ModRM byte which follows the opcode. Obviously, we can't fit 3 registers in the ModRM byte because it's only 8-bits.
In `op reg1, [reg2 + reg3]`, reg1 is encoded in the ModRM byte. The 3 bits that were previously used for reg2 are instead `0b100`, which indicates a SIB byte follows the ModRM byte. The SIB (Scale-Index-Base) byte uses 3 bits each for reg2 and reg3 as the base and index registers.
In any other instruction, the SIB byte is used for addressing, so syntax of `lea` is consistent with the way it is encoded.
Encoding details of ModRM/SIB are in Volume2, Section 2.1.5 of the ISA manual: https://www.intel.com/content/www/us/en/developer/articles/t...
[1] On a hardware level, the ModR/M encoding of most x86 instructions allows you to specify a register operand and either a memory or a register operand. The LEA instruction only allows a register and a memory operand to be specified; if you try to use a register and register operand, it is instead decoded as an illegal instruction.
Not quite unique: the now-deprecated Intel MPX instructions had similar semantics, e.g. BNDCU or BNDMK. BNDLDX/BNDSTX are even weirder as they don't compute the address as specified but treat the index part of the memory operand separately.
LEA would normally be used for things like calculating address of an array element, or doing pointer math.