Я хотел бы знать, какая разница между этими инструкциями:
MOV AX, [TABLE-ADDR]
и
LEA AX, [TABLE-ADDR]
Я хотел бы знать, какая разница между этими инструкциями:
MOV AX, [TABLE-ADDR]
и
LEA AX, [TABLE-ADDR]
Короче говоря, 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]
. (т.е. mov r32, imm32
)
lea eax, [var+16]
== mov eax, var+16
lea eax, [eax*4]
== shl eax, 2
(но без установки флагов)
В синтаксисе MASM используйте OFFSET var
, чтобы получить mov-instant вместо нагрузки.
Инструкция MOV reg, addr означает чтение переменной, хранящейся в адресе addr, в регистр reg. Инструкция LEA reg, addr означает считывание адреса (а не переменной, хранящейся по адресу) в регистровую рег.
Другая форма инструкции MOV - это регистр MOV, immdata, который означает считывание непосредственных данных (то есть констант) immdata в регистр reg. Обратите внимание, что если addr в регистре LEA, addr является просто константой (т.е. Фиксированным смещением), то эта инструкция LEA по существу точно такая же, как эквивалентная инструкция MOV reg, immdata, которая загружает ту же константу, что и непосредственные данные.
Если вы укажете только литерал, нет никакой разницы. LEA имеет больше возможностей, и вы можете прочитать о них здесь:
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
и NOT offset на 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 - это "MOVe", фактически копия адреса, на который указывает метка TABLE-ADDR. Инструкция LEA представляет собой "Load Effective Address", который является косвенной инструкцией, что означает, что TABLE-ADDR указывает на ячейку памяти, в которой найден адрес для загрузки.
Эффективно использование LEA эквивалентно использованию указателей в таких языках, как C, как таковое, это мощная инструкция.
В принципе... "Перейдите в REG... после вычисления..." это кажется хорошим и для других целей:)
если вы просто забыли, что это значение является указателем вы можете использовать его для оптимизации/минимизации кода... что когда-либо..
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