Lea assembler что это
Перейти к содержимому

Lea assembler что это

Команда LEA

Команда LEA в Ассемблере вычисляет эффективный адрес ИСТОЧНИКА и помещает его в ПРИЁМНИК. Синтаксис:

LEA ПРИЁМНИК, ИСТОЧНИК

После выполнения этой команды флаги не изменяются.

Обратите внимание, что ИСТОЧНИКОМ может быть только переменная (ячейка памяти), а ПРИЁМНИКОМ — только регистр (но не сегментный).

Что такое эффективный адрес

Прежде чем продолжить рассказ об инструкции LEA, напомню, что такое эффективный адрес.

Не люблю я иностранные слова — они только путаницу вносят. Но так уж повелось на Руси — если иностранные словечки не употребляешь, значит — лох. В итоге часто люди сами не понимают, что говорят, а исконно русские и понятные слова уже давно забыты и найти подходящую замену иностранному слову бывает непросто (даже мне при всём желании))).

Так вот, слово “эффективный” можно перевести на русский как “действенный”, “действующий”, “настоящий”. Что касается программистской терминологии, то в некоторых источниках вместо “эффективный адрес” встречается словосочетание “текущий адрес” или даже “виртуальный адрес”.

Слишком глубоко в адресацию погружаться не будем. Если вы совершенно далеки от этого, то можете изучить мою контрольную работу по этой теме университетских времён (эх, давно это было…)

Ну а если кратко, то эффективный (текущий) адрес — это

БАЗА + СМЕЩЕНИЕ + ИНДЕКС

где БАЗА — это базовый адрес, находящийся в регистре (при 16-разрядной адресации могут использоваться только регистры BX или BP); СМЕЩЕНИЕ (или ОТКЛОНЕНИЕ — displacement) — это константа (число со знаком), заданная в команде; ИНДЕКС — значение индексного регистра (при 16-разрядной адресации могут использоваться только регистры SI или DI).

Любая из частей эффективного адреса может отсутствовать (например, необязательно указывать СМЕЩЕНИЕ или ИНДЕКС), но обязательно должна присутствовать хотя бы одна часть (например, только БАЗА).

Вычисление эффективного адреса

Ну а теперь чуть подробнее о самой команде LEA. Как уже было сказано, она выполняет вычисление адреса в Ассемблере. В итоге в ПРИЁМНИК записывается адрес памяти (точнее, только смещение).

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

Если адрес 32-разрядный, а ПРИЁМНИК — 16-разрядный, то старшая половина вычисленного адреса теряется. Если наоборот, ПРИЁМНИК — 32-разрядный, а адрес 16-разрядный, то вычисленное смещение дополняется нулями.

Команда LEA позволяет определить текущее смещение косвенного операнда любого типа. Так как при косвенной адресации может использоваться один или два регистра общего назначения, то приходится каким-то образом вычислять текущее смещение операнда во время выполнения программы.

Команду LEA также удобно применять для определения адреса параметра, находящегося в стеке. Например, если в процедуре определяется локальный массив, то для работы с ним часто необходимо загрузить его смещение в индексный регистр (что как раз таки можно сделать командой LEA).

Оператор OFFSET позволяет определить смещение только при компиляции, и в отличие от него команда LEA может сделать это во время выполнения программы. Хотя в остальных случаях обычно вместо LEA используют MOV и OFFSET, то есть

LEA ПРИЁМНИК, ИСТОЧНИК

это то же самое, что и

MOV ПРИЁМНИК, offset ИСТОЧНИК

При этом следует помнить об указанных выше ограничениях применения оператора OFFSET.

Ещё один пример:

После выполнения этой программы в AX будет записано значение 0104h. Команда LEA занимает 3 байта, команда RET занимает 1 байт. Мы начинаем с адреса 100h, поэтому адрес переменной Х — это 104h (100h + 3 + 1 = 104h). Команда LEA вычислила этот адрес и записала его в указанный регистр (в нашем случае в АХ).

Команда LEA в арифметических операциях

Инструкция LEA часто используется для арифметических операций, таких как умножение и сложение. Преимущество такого способа в том, что команда LEA занимает меньше места, чем команды арифметических операций. Кроме того, в отличие от последних, она не изменяет флаги. Примеры:

Обратите внимание на то, что адресацию со смещением, где используется знак умножения (*), не поддерживает эмулятор emu8086 (возможно, некоторые другие эмуляторы тоже). Поэтому в данном эмуляторе первый пример не будет работать правильно. Второй же пример (сложение), будет работать.

Напоследок, как всегда, о происхождении аббревиатуры LEA.

LEALoad Effective Address (загрузить эффективный адрес).

LEA — Load Effective Address

Computes the effective address of the second operand (the source operand) and stores it in the first operand (destination operand). The source operand is a memory address (offset part) specified with one of the processors addressing modes; the destination operand is a general-purpose register. The address-size and operand-size attributes affect the action performed by this instruction, as shown in the following table. The operand-size attribute of the instruction is determined by the chosen register; the address-size attribute is determined by the attribute of the code segment.

Operand Size Address Size Action Performed
16 16 16-bit effective address is calculated and stored in requested 16-bit register destination.
16 32 32-bit effective address is calculated. The lower 16 bits of the address are stored in the requested 16-bit register destination.
32 16 16-bit effective address is calculated. The 16-bit address is zero-extended and stored in the requested 32-bit register destination.
32 32 32-bit effective address is calculated and stored in the requested 32-bit register destination.

Table 3-54. Non-64-bit Mode LEA Operation with Address and Operand Size Attributes

Different assemblers may use different algorithms based on the size attribute and symbolic reference of the source operand.

In 64-bit mode, the instruction’s destination operand is governed by operand size attribute, the default operand size is 32 bits. Address calculation is governed by address size attribute, the default address size is 64-bits. In 64-bit mode, address size of 16 bits is not encodable. See Table 3-55.

Lea assembler что это

Вычислить эффективный адрес операнда m и поместить результат в r16

Вычислить эффективный адрес операнда m и поместить результат в r32

Команда LEA вычисляет эффективный адрес (смещение) операнда-источника команды (который должен быть операндом в памяти) и сохраняет его в регистре — операнде-назначении команды. Атрибут размера операнда команды определяется выбранным регистром (16- или 32-битным). Атрибут размера адреса определяется атрибутом текущего кодового сегмента. Атрибуты размера адреса и размера операнда воздействуют на операцию, выполняемую командой LEA так, как это показано в таблице 6.65.

Таблица 6.65. Воздействие атрибутов размера операнда и размера адреса на действие команды LEA

Размер операнда

Размер адреса

Выполняемая операция

Вычисляется 16-битный эффективный адрес и сохраняется в 16-битном регистре-назначении

Вычисляется 32-битный эффективный адрес его младшие 16 бит сохраняются в 16-битном регистре-назначении

Вычисляется 16-битный эффективный адрес, затем знакорасширяется и сохраняется в 32-битном регистре-назначении

Вычисляется 32-битный эффективный адрес и сохраняется в 32-битном регистре-назначении

IF OperandSize = 16 AND AddressSize = 16

DEST = EffectiveAddress(SRC); (* 16- битный адрес *)

ELSE IF OperandSize = 16 AND AddressSize = 32 THEN

temp = EffectiveAddress(SRC); (* 32- битный адрес *)

DEST = temp[0..15]; (* 16- битный адрес *)

ELSE IF OperandSize = 32 AND AddressSize = 16 THEN

temp = EffectiveAddress(SRC); (* 16- битный адрес *)

DEST = ZeroExtend(temp); (* 32- битный адрес *)

ELSE IF OperandSize = 32 AND AddressSize = 32 THEN

DEST = EffectiveAddress(SRC); (* 32- битный адрес *)

#UD, если второй операнд не является операндом в памяти.

#UD, если второй операнд не является операндом в памяти.

#UD, если второй операнд не является операндом в памяти.

Различные ассемблеры могут по разному интерпретировать команду в зависимости от атрибута размера и символической ссылки второго операнда.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *