What is the difference between MOV and LEA?
-
19-09-2019 - |
Question
I would like to know what the difference between these instructions is:
MOV AX, [TABLE-ADDR]
and
LEA AX, [TABLE-ADDR]
Solution
LEA
means Load Effective AddressMOV
means Load Value
In short, LEA
loads a pointer to the item you're addressing whereas MOV loads the actual value at that address.
The purpose of LEA
is to allow one to perform a non-trivial address calculation and store the result [for later usage]
LEA ax, [BP+SI+5] ; Compute address of value
MOV ax, [BP+SI+5] ; Load value at that address
Where there are just constants involved, MOV
(through the assembler's constant calculations) can sometimes appear to overlap with the simplest cases of usage of LEA
. Its useful if you have a multi-part calculation with multiple base addresses etc.
OTHER TIPS
In NASM syntax:
mov eax, var == lea eax, [var] ; i.e. mov r32, imm32
lea eax, [var+16] == mov eax, var+16
lea eax, [eax*4] == shl eax, 2 ; but without setting flags
In MASM syntax, use OFFSET var
to get a mov-immediate instead of a load.
The instruction MOV reg,addr means read a variable stored at address addr into register reg. The instruction LEA reg,addr means read the address (not the variable stored at the address) into register reg.
Another form of the MOV instruction is MOV reg,immdata which means read the immediate data (i.e. constant) immdata into register reg. Note that if the addr in LEA reg,addr is just a constant (i.e. a fixed offset) then that LEA instruction is essentially exactly the same as an equivalent MOV reg,immdata instruction that loads the same constant as immediate data.
If you only specify a literal, there is no difference. LEA has more abilities, though, and you can read about them here:
http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-1.html#HEADING1-136
It depends on the used assembler, because
mov ax,table_addr
in MASM works as
mov ax,word ptr[table_addr]
So it loads the first bytes from table_addr
and NOT the offset to table_addr
. You should use instead
mov ax,offset table_addr
or
lea ax,table_addr
which works the same.
lea
version also works fine if table_addr
is a local variable e.g.
some_procedure proc
local table_addr[64]:word
lea ax,table_addr
Basically ... "Move into REG ... after computing it..." it seems to be nice for other purposes as well :)
if you just forget that the value is a pointer you can use it for code optimizations/minimization ...what ever..
MOV EBX , 1
MOV ECX , 2
;//with 1 instruction you got result of 2 registers in 3rd one ...
LEA EAX , [EBX+ECX+5]
EAX = 8
originaly it would be:
MOV EAX, EBX
ADD EAX, ECX
ADD EAX, 5
The difference is subtle but important. The MOV instruction is a 'MOVe' effectively a copy of the address that the TABLE-ADDR label stands for. The LEA instruction is a 'Load Effective Address' which is an indirected instruction, which means that TABLE-ADDR points to a memory location at which the address to load is found.
Effectively using LEA is equivalent to using pointers in languages such as C, as such it is a powerful instruction.