В чем разница между MOV и LEA?

Я хотел бы знать, в чем разница между этими инструкциями:

MOV AX, [TABLE-ADDR]

и

LEA AX, [TABLE-ADDR]

7 ответов


  • LEA означает загрузить эффективный адрес
  • MOV означает значение нагрузки

короче, LEA загружает указатель на элемент, к которому вы обращаетесь, тогда как MOV загружает фактическое значение по этому адресу.

цель LEA позволяет выполнить нетривиальный расчет адреса и сохранить результат [для последующего использования]

LEA ax, [BP+SI+5] ; Compute address of value

MOV ax, [BP+SI+5] ; Load value at that address

где участвуют только константы,MOV (через сборщика постоянные вычисления) иногда могут перекрываться с простейшими случаями использования LEA. Его полезно, если у вас есть многозначный расчет с несколькими базовыми адресами и т. д.


в синтаксисе NASM:

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

в синтаксисе MASM используйте OFFSET var чтобы получить mov-immediate вместо нагрузки.


инструкция MOV reg, addr означает чтение переменной, хранящейся по адресу addr в register reg. Инструкция LEA reg, addr означает чтение адреса (а не переменной, хранящейся по адресу) в register reg.

другой формой инструкции MOV является MOV reg, immdata, что означает чтение непосредственных данных (т. е. постоянных) immdata в register reg. Обратите внимание, что если addr в Lea reg, addr является просто константой (т. е. фиксированным смещением) , то эта инструкция LEA по существу является то же,что и эквивалентная инструкция MOV reg, immdata, которая загружает ту же константу, что и непосредственные данные.


Если вы укажете только литерал, разницы нет. Однако у Леа больше способностей, и вы можете прочитать о них здесь:

http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-1.html#HEADING1-136


это зависит от используемого ассемблера, потому что

mov ax,table_addr

в MASM работает как

mov ax,word ptr[table_addr]

таким образом, он загружает первые байты из table_addr, а не смещение table_addr. Вы должны использовать вместо

mov ax,offset table_addr

или

lea ax,table_addr

, который работает так же.

lea версия также отлично работает, если table_addr является локальной переменной, например

some_procedure proc

local table_addr[64]:word

lea ax,table_addr

в принципе ... - Переезжай в Редж ... после вычисления..." кажется, это хорошо и для других целей:)

Если вы просто забудете, что значение является указателем вы можете использовать его для оптимизации/минимизации кода ...чем когда-либо..

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

первоначально это будет:

MOV EAX, EBX
ADD EAX, ECX
ADD EAX, 5

разница тонкая, но важная. Инструкция MOV-это "перемещение", фактически копия адреса, который обозначает метка TABLE-ADDR. Инструкция LEA - это "эффективный адрес загрузки", который является косвенной инструкцией, что означает, что TABLE-ADDR указывает на местоположение памяти, в котором найден адрес для загрузки.

эффективное использование LEA эквивалентно использованию указателей на таких языках, как C, поэтому это мощная инструкция.