Difference between lea and offset
Asked Answered
G

3

18
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

Gil answered 9/5, 2010 at 11:7 Comment(2)
the only difference between them is that lea is an instruction and offset is notTellurize
Possible duplicate of What is the difference between MOV and LEA?Tellurize
L
26

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.

Lexis answered 9/5, 2010 at 11:21 Comment(6)
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.Akins
@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).Sena
@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.Akins
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.Accountable
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.Accountable
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.)Sena
D
3

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
Discussion answered 4/6, 2016 at 15:19 Comment(0)
E
-1

You can use them to do the same thing but, LEA will always be better if the address is a little complex.

consider that you have the following array of chars:

ASC_TBL DB '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'

if you want to get the 6th element '5' you would do something like this using offset:

mov ax, offset ASC_TBL

add ax, 5h; flags [PF] will be affected 

On the other hand, if you are using the LEA instruction you can simply use one instruction like this:

LEA ax, [ASC_TBL + 5h]; no flags are affected

Notice that:

  • Although using LEA proved that it has an advantage over using offset, it's more efficient to use offset if the address isn't very complex to write or both of them will do the same thing with the same number of instructions. The reason is that offset ASC_TBL is calculated during translation - like being be preprocessed- but, LEA is an actual processor instruction.

  • you can't use the offset instruction to get the addresses that aren't known before the compilation time.

Expressage answered 18/11, 2020 at 19:57 Comment(3)
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.Sena
I didn't say that +5 is being done at runtime, I said that the full LEA instruction is an actual processor instructionExpressage
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.Sena

© 2022 - 2024 — McMap. All rights reserved.