В этом случае LEA и MOV делают то же самое. LEA более мощный инструмент, чем MOV, если вы хотите вычислить адрес более сложным способом. Допустим, вы хотите получить адрес n-го символа в вашем массиве, а n хранится в bx. С MOV вам нужно написать следующие две инструкции:
Mov dx, offset ar add dx, bx
С помощью lea вы можете сделать это с помощью всего одной инструкции:
lea dx, [ar + bx]
Еще одна вещь, которую следует учитывать здесь: add dx,bx инструкция изменит флаги состояния ЦП. Добавление сделано внутри lea dx, [ar + bx] инструкция, с другой стороны, никоим образом не изменяет флаги, потому что она не считается арифметической инструкцией.
Это иногда полезно, если вы хотите сохранить флаги при выполнении некоторых простых вычислений (вычисления адресов очень распространены). Сохранение и восстановление регистра флага — выполнимая, но медленная операция.
ответ дан 09 мая ’10, 12:05
Также offset ar — это непосредственная стоимость, которая рассчитывается при переводе. А также lea — это фактическая инструкция процессора «Загрузить эффективный адрес» со вторым операндом, который ссылается на память. — оны
Команда LEA
Кроме того, это было проблемой в старые времена программирования в 16-битном реальном режиме. При связывании с небольшим двоичным файлом .com, где все находится в одном сегменте, вы можете использовать offset or lea взаимозаменяемы большую часть времени, но работая с моделями памяти, отличными от tiny вызовет много проблем, так как offset относительно базового адреса сегмента, в котором определены данные. — Ловушка
Цитата из Assembly Language for x86 Processors, 7e, KIP R. IRVINE
Невозможно использовать OFFSET для получения адреса параметра стека, потому что OFFSET работает только с адресами, известными во время компиляции. Следующее утверждение не соберется:
mov esi,OFFSET [ebp-30] ; error
Источник: stackovergo.com
Команда LEA
Команда LEA позволяет загрузить в регистр адрес, вычисленный по смещению, заданному во втором операнде. Отличается от использования директивы offset тем, что позволяет вычислить адрес на этапе исполнения программы. Также иногда используется для умножения целых чисел, например команда LEA EAX, [ECX+ECX*4] загрузит в регистр EAX значение ECX * 5.
Команда LEA
Синтаксис: | LEA op1,op2 |
Операнды: | op1 — r16/32 op2 — m16/32 |
Назначение: | Загрузка исполнительного адреса |
Процессор: | 8086+ |
Флаги: | Не изменяются |
Комментарий: | Команда LEA вычисляет исполнительный адрес (смещение) второго операнда и записывает его в регистр, заданный первым операндом |
Ограничения: | Нет |
Примеры: | lea ax,[bx+8] lea bx,buf[si] |
Ассемблер от А до Я Урок 4. offset, lea
- Уголок в Вконтакте
- Уголок в Телеграм
- Уголок в YouTube
Источник: sysprog.ru
Команды загрузки адресных значений
Команда загрузки исполнительного адреса LEA имеет формат:
LEA регистр16, память
и загружает в указанный 16-битный регистр адрес (смещение offset) указанной ячейки памяти, адресуемой любым способом.
Во многих случаях команда LEA идентична команде MOV с директивой OFFSET. Однако, следует помнить, что при использовании директивы OFFSET адрес вычисляется и должен быть известен на этапе трансляции программы, а при использовании команды LEA при ее выполнении. Следовательно, при обращении к индексированной переменной с регистровым индексом (например, Tabl[SI]), неизвестным при трансляции, команда LEA правильно сформирует адрес элемента данных, а команда MOV OFFSET неправильно. Директива OFFSET в подобных условиях возвращает адрес переменной без учета индекса, что приводит к возникновению ошибки, необнаруживаемой в процессе трансляции программы.
Пример 3.49:
Пусть имеется сегмент данных:
Data SEGMENT
Tabl DB 20h, 21h, 22h, 23h, 24h, 25h
Тогда при обращениях к таблице Tabl, получим:
LEA BX, Tabl ;Идентично MOV BX, OFFSET Tabl
MOV AL, [BX] ;(AL)=20h
LEA BX, Tabl[4] ;Идентично MOV BX, OFFSET Tabl[4]
MOV AL, [BX] ;(AL)=24h
LEA BX, Tabl[SI] ;Корректно
MOV AL, [BX] ;(AL)=23h
MOV BX, OFFSET Tabl[SI];Необнаруживаемая ошибка MOV AL, [BX] ;Ошибка – (AL)=20h
Команды загрузки полных адресных значений LDS и LES имеют формат:
LDS регистр16, память32
LES регистр16, память32
и осуществляют загрузку двойного слова из ячейки памяти, адресуемой любым способом, в соответствующий сегментный регистр и указанный 16-битный регистр. При этом младшее слово, расположенное по адресу «память32», загружается в 16-битный регистр, а старшее слово, считываемое по адресу «память32+2», командой LDS загружается в регистр DS, а командой LES — в регистр ES. В соответствии с этим младшее слово области «память32» должно содержать смещение offset, а старшее слово — сегментную компоненту segment выбираемой переменной. Так как команды LDS и LES загружают полный логический адрес, то программа может сразу обращаться к объекту, на который указывает этот адрес.
Обычно буфера адресных указателей инициализируются на требуемые значения директивой DD при трансляции программы. При необходимости они могут переопределяться двумя командами MOV с директивами SEG и OFFSET. Это приемлемо, так как программа читает адресные указатели гораздо чаще, чем изменяет их.
Команды LDS и LES наиболее часто используются для инициализации регистров при обработке строк.
Пример 3.50:
Скопировать элемент одной строки в две других строки:
String1 DB 80 DUP(?) ;Описание строк
String2 DB 80 DUP(?)
String3 DB 80 DUP(?)
BuffSrc DD String1 ;Инициализация адресного буфера
;источника на String1
BuffDst DD String2 ;Инициализация адресного буфера
;приемника на String2
LDS SI,BuffSrc ;Инициализация DS:SI на строку-источник
LES DI,BuffDst ;Инициализация ES:DI на строку-приемник
MOV AL,[SI] ;Копирование элемента
MOV ES:[DI],AL ;String1 в String2
MOV AX,OFFSET String3 ;Переопределение адресного указателя
MOV WORD PTR BuffDst,AX ;приемника на String3
MOV AX,SEG String3
MOV WORD PTR BuffDst+2,AX
LDS SI,BuffSrc ;Инициализация DS:SI на строку- источник
LES DI,BuffDst ;Инициализация ES:DI на строку- приемник
MOV AL,[SI] ;Копирование элемента
MOV ES:[DI],AL ;String1 в String3.
Источник: studfile.net