Difference between lea and offset
Solution 1
In this use-case LEA and MOV do the same thing. LEA is more powerful than MOV if you want to calculate an address in a more complex way.
Lets for example say you want to get the address of the n'th character in your array, and the n is stored in bx. With MOV you have to write the following two instructions:
Mov dx, offset ar
add dx, bx
With lea you can do it with just one instruction:
lea dx, [ar + bx]
Another thing to consider here: the add dx,bx
instruction will change the status flags of the CPU. The addition done inside the lea dx, [ar + bx]
instruction on the other hand does not change the flags in any way because it is not considered an arithmetic instruction.
This is sometimes helpful if you want to preserve the flags while doing some simple calculations (address calculations are very common). Storing and restoring the flag-register is doable but a slow operation.
Solution 2
Quote from Assembly Language for x86 Processors, 7e, KIP R. IRVINE
It is not possible to use OFFSET to get the address of a stack parameter because OFFSET only works with addresses known at compile time. The following statement would not assemble:
mov esi,OFFSET [ebp-30] ; error
userBI
Updated on July 14, 2022Comments
-
userBI almost 2 years
ar db "Defference $"
What's the difference between
mov dx,offset ar
and
lea dx,ar
I think both are doing same work, but what is the difference between these two
-
ony about 14 yearsAlso
offset ar
- is immediate value which is calculated during translation. Andlea
- is actual processor instruction "Load Effective Address" with second operand which references to memmory. -
Peter Cordes about 8 years@ony:
lea
is just a shift-and-add instruction. It never actually loads from memory, it just uses the addressing-mode syntax and binary encoding. In the OP's case, withlea
on an absolute address, thedisp16
is the same as theimm16
for themov
, both calculated the same way at assemble time (actually at link time when the final address is known). -
ony about 8 years@PeterCordes, I didn't said that
lea
loads anything (reference is just a reference). I said that it is a real x86 instruction. If you do calculatons that can be done during translation you can usemov
. -
Trap over 6 yearsThe thing that puzzles me most about
lea
is the syntax used by compilers and debuggers.lea ax, [addr]
for me is something like "do something with the contents ofaddr
and put the result intoax
, which is not the case. -
Trap over 6 yearsAlso, this was an issue in the older days of 16-bit real mode programming. When linking to a small binary .com file where everything was in the same segment, you could use
offset
orlea
interchangeably most of the time, but working with memory models other thantiny
would cause a lot of problems sinceoffset
is relative to the segment base address where the data is defined. -
Peter Cordes over 5 yearsWorth mentioning that you should never use
lea dx, [ar]
. It's one byte longer thanmov
, and no faster. For a static address with no register index, you only ever want LEA on x86-64, for RIP-relative (position-independent) 64-bit addressing. Otherwise, always use mov-immediate if you need a plain static address in a register. (On x86-64 in position-dependent code,mov edi, offset mydata
is still optimal, e.g. on Linux where static data is in the low 32 bits of virtual address space, so 32-bit absolute addresses can be used for efficiency.) -
Peter Cordes over 3 years
mov ax, offset ASC_TBL + 5
is legal, and shorter (3 bytes formov ax, imm16
vs. 4 bytes for LEA: opcode + modrm + disp16). Either way the absolute address is calculated by the assembler (or linker) and embedded into the machine code.ASC_TBL+5
is a link-time constant just likeASC_TBL
; there's no+5
being done at runtime. Symbols don't really exist at runtime, except as debug metadata in the executable. The CPU isn't searching for them when running instructions that reference them. -
Mostafa Wael over 3 yearsI didn't say that
+5
is being done at runtime, I said that the fullLEA
instruction is an actual processor instruction -
Peter Cordes over 3 yearsOk, so you just weren't aware you could
mov ax, offset ASC_TBL + 5
. Well, you can. :P The assembler (and linker if you're not making a flat binary) handle it with an identical mechanism to what they use to fill in[disp16]
field in thelea
operand. Themov reg, imm16
encoding also just needs an absolute address in the machine code. LEA is worse for code-size and should never be used for this, except in 64-bit code with RIP-relative addressing to get position-independence or instead of 64-bit absolute addresses.