Difference between lea and offset

17,780

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
Share:
17,780
userBI
Author by

userBI

Updated on July 14, 2022

Comments

  • userBI
    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
    ony about 14 years
    Also offset ar - is immediate value which is calculated during translation. And lea - is actual processor instruction "Load Effective Address" with second operand which references to memmory.
  • Peter Cordes
    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, with lea on an absolute address, the disp16 is the same as the imm16 for the mov, both calculated the same way at assemble time (actually at link time when the final address is known).
  • ony
    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 use mov.
  • Trap
    Trap over 6 years
    The 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 of addr and put the result into ax, which is not the case.
  • Trap
    Trap over 6 years
    Also, 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 or lea interchangeably most of the time, but working with memory models other than tiny would cause a lot of problems since offset is relative to the segment base address where the data is defined.
  • Peter Cordes
    Peter Cordes over 5 years
    Worth mentioning that you should never use lea dx, [ar]. It's one byte longer than mov, 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
    Peter Cordes over 3 years
    mov ax, offset ASC_TBL + 5 is legal, and shorter (3 bytes for mov 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 like ASC_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
    Mostafa Wael over 3 years
    I didn't say that +5 is being done at runtime, I said that the full LEA instruction is an actual processor instruction
  • Peter Cordes
    Peter Cordes over 3 years
    Ok, 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 the lea operand. The mov 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.