Possible Duplicate:
What's the purpose of the LEA instruction?
When I need the value at an address I can use the effective address e.g. push dword [str+4]
. But when I need to reference an address -- I can't use push dword str+4
(which to me is the obvious and intiutive way to do it).
Instead need to use lea EAX, [str+4]
and then push EAX
. This a bit confusing and also gives an extra processor instruction, albeit a 'zero-clock' one. (See this answer)
Is there some hardware level explaination for this difference, or is it just a quirk of (NASM) assembly syntax?
Edit: Okay so this comment asks the same question as me. And it is answered in this comment just as Lucero's answer - the X86 does not support such addressing.
push str+4
does work in 32-bit code, assuming str
is a normal symbol/label like str:
, not a macro alias for a register like %define str edi
or something.
On a symbol address, str+4
is computed by the linker while building the executable, using a relocation entry in the .o
object file created by NASM. The machine code for push str+4
includes the same 4-byte absolute address (as an imm32) that lea eax, [str+4]
does (as a disp32 in the addressing mode). (This is not 64-bit code so RIP-relative addressing with default rel
isn't a possibility.)
If str
actually is a macro for a register, then the +4
computation would have to happen at run-time and you would indeed need a separate instruction from the push
.
Assembly instructions directly represent x86 opcodes (no transforming compilation takes place as in higher-level languages). The opcodes have their limitations in what they can represent; as such, while address computations are possible as part of the x86 addressing, value computations are not. LEA covers this gap by storing the result of the address computation in any register instead of only consuming it internally.