Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Консп_АПЗ_ПК_12_1.doc
Скачиваний:
31
Добавлен:
23.11.2019
Размер:
624.13 Кб
Скачать

7.2. Операнды команд языка Ассемблера

Данные, которые обрабатываются командами, называются операндами. Операнды в языке ассемблера записываются непосредственно после команды, если их несколько, то через запятую.

Одни команды вообще не имеют никаких операндов, другие имеют один или два операнда. В качестве операнда можно указать непосредственное значение (например, 0x123), имя регистра или ссылку на ячейку памяти (так называемые косвенные операнды). Что же касается разрядности, имеются 32-разрядные, 16-разрядные, и 8-разрядные операнды. Почти каждая команда требует, чтобы операнды были одинакового размера (разрядности). Команда

MOV АХ,0x1234

имеет два операнда: операнд регистра и непосредственное значение, и оба они 16-битные.

Последний тип операнда – косвенный тип – адресует данные, находящиеся в памяти, получает их из памяти и использует в качестве значения. Узнать этот операнд очень просто – по наличию в записи квадратных скобок.

В документации по Ассемблеру различные форматы операндов представлены следующими аббревиатурами:

reg8-операнд – любой 8-разрядный регистр общего назначения;

regl6-onepaнд – любой 16-разрядный регистр общего назначения;

reg32-onepaнд – любой 32-разрядный регистр общего назначения;

m – операнд может находиться в памяти;

imm8 – непосредственное 8-разрядное значение;

imml6 – непосредственное 16-разрядное значение;

imm32 – непосредственное 32-разрядное значение;

segreg – операнд должен быть сегментным регистром.

Допускаются неоднозначные типы операндов, например: reg8/imm8-onepaнд может быть любым 8-битным регистром общего назначения или любым 8-битным непосредственным значением.

Иногда размер операнда определяется только по последнему типу, например, следующая запись аналогична предыдущей: R/imm8-onepaнд может быть любым регистром (имеется в виду 8-битный регистр) общего назначения или 8-разрядным значением.

7.3. Способы адресации памяти языка Ассемблера

Адрес, как и сама команда, – это число. Чтобы не запоминать адреса всех «переменных», используемых в программе, этим адресам присваивают символические обозначения, которые называются переменными (иногда их также называют указателями).

В языке Ассемблера используются непосредственная, прямая и косвенная адресации. При использовании косвенного операнда адрес в памяти, по которому находится нужное значение, записывается в квадратных скобках: [адрес]. Если мы используем указатель, то есть символическое представление адреса, например, [ESI], то в листинге машинного кода мы увидим, что указатель был заменен реальным значением адреса. Можно также указать точный адрес памяти, например, [0x594F].

Чаще всего мы будем адресовать память по значению адреса, занесенному в регистр процессора. Чтобы записать такой косвенный операнд, нужно просто написать имя регистра в квадратных скобках. Например, если адрес загружен в регистр ESI, вы можете получить данные, расположенные по этому адресу, используя выражение [ESI].

Рассмотрим ситуацию, когда регистр ESI содержит адрес первого элемента (нумерация начинается с 0) в массиве байтов. Как получить доступ, например, ко второму элементу (элементу, адрес которого на 1 байт больше) массива?

Процессор поддерживает сложные способы адресации, которые очень нам пригодятся в дальнейшем. В нашем случае, чтобы получить доступ ко второму элементу массива, нужно записать косвенный операнд [ESI + 1].

Имеются даже более сложные типы адресации: [адрес + ЕВХ + 4]. В этом случае процессор складывает адрес, значение 4 и значение, содержащееся в регистре ЕВХ. Результат этого выражения называется эффективным адресом (ЕА, Effective Address) и используется в качестве адреса, по которому фактически находится операнд.

При вычислении эффективного адреса процессор 80386+ также позволяет умножать один член выражения на константу, являющуюся степенью двойки: [адрес + ЕВХ * 4]. Корректным считается даже следующее «сумасшедшее» выражение: [число - 6 + ЕВХ * 8 + ESI].

На практике чаще всего довольствуются только одним регистром [ESI] или суммой регистра и константы, например, [ESI + 4]. В зависимости от режима процессора, мы можем использовать любой 16-разрядный или 32-разрядный регистр общего назначения [ЕАХ], [ЕВХ],... [ЕВР].

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