Операнд задается неявно на микропрограммном уровне. В этом случае команда явно не содержит операндов. Алгоритм выполнения команды использует некоторые объекты по умолчанию (регистры, флаги в eflags и т. д.).
Например, команды cli и sti неявно работают с флагом прерывания if в регистре eflags, а команда xlat неявно обращается к регистру al и строке в памяти по адресу, определяемому парой регистров ds:bx.
Операнд задается в самой команде (непосредственный операнд). Операнд находится в коде команды, то есть является ее частью. Для хранения такого операнда в команде выделяется поле длиной до 32 бит (см. рисунок 2.2). Непосредственный операнд может быть только вторым операндом (источником). Операнд получатель может находиться либо в памяти, либо в регистре.
Например: mov ax,0ffffh пересылает в регистр ax шестнадцатеричную константу ffff. Команда add sum,2 складывает содержимое поля по адресу sum с целым числом 2 и записывает результат по месту первого операнда, то есть в память.
Операнд находится в одном из регистров. Регистровые операнды указываются именами регистров. В качестве регистров могут использоваться:
– 32-разрядные регистры EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP;
– 16-разрядные регистры AX, BX, CX, DX, SI, DI, SP, BP;
– 8-разрядные регистры AH, AL, BH, BL, CH, CL, DH, DL;
– сегментные регистры CS, DS, SS, ES, FS, GS.
Например, команда add ax,bx складывает содержимое регистров ax и bx и записывает результат в bx. Команда dec si уменьшает содержимое si на 1.
Операнд располагается в памяти. Это наиболее сложный и в то жe время наиболее гибкий способ задания операндов. Он позволяет реализовать следующие два основных вида адресации: прямую и косвенную.
В свою очередь, косвенная адресация имеет следующие разновидности:
– косвенная базовая адресация; другое ее название – регистровая косвенная адресация;
– косвенная базовая адресация со смещением;
– косвенная индексная адресация со смещением;
– косвенная базовая индексная адресация;
– косвенная базовая индексная адресация со смещением.
Операндом является порт ввода/вывода. Как мы уже отмечали, помимо адресного пространства оперативной памяти микропроцессор поддерживает адресное пространство ввода-вывода, которое используется для доступа к устройствам ввода-вывода. Объем адресного пространства ввода-вывода составляет 64 Кбайт. Для любого устройства компьютера в этом пространстве выделяются адреса. Конкретное значение адреса в пределах этого пространства называется портом ввода-вывода. Физически порту ввода-вывода соответствует аппаратный регистр (не путать с регистром микропроцессора), доступ к которому осуществляется с помощью специальных команд ассемблера in и out.
Например,
in al,60h ;ввести байт из порта 60h
Регистры, адресуемые с помощью порта ввода-вывода, могут иметь разрядность 8, 16 или 32 бит, но для конкретного порта разрядность регистра фиксирована.
Команды in и out работают с фиксированной номенклатурой объектов. В качестве источника информации или получателя применяются так называемые регистры-аккумуляторы eax, ax, al. Выбор регистра определяется разрядностью порта. Номер порта может задаваться непосредственным операндом в командах in и out или значением в регистре dx. Последний способ позволяет динамически определить номер порта в программе.
Например:
mov dx,20h ;записать номер порта 20h в регистр dx mov al,20h ;записать значение 20h в регистр al out dx,al ;вывести значение 20h в порт 20H |
Операнд находится в стеке.
Команды могут совсем не иметь операндов, иметь один или два операнда. Большинство команд требуют двух операндов, один из которых является операндом-источником, а второй – операндом назначения. Важно то, что один операнд может располагаться в регистре или памяти, а второй операнд обязательно должен находиться в регистре или непосредственно в команде. Непосредственный операнд может быть только операндом-источником. В двухоперандной машинной команде возможны следующие сочетания операндов:
– регистр–регистр;
– регистр–память;
– память–регистр;
– непосредственный операнд–регистр;
– непосредственный операнд–память.
У данного правила есть исключения, которые касаются:
– команд работы с цепочками, которые могут перемещать данные из памяти в память;
– команд работы со стеком, которые могут переносить данные из памяти в стек, также находящийся в памяти;
– команд типа умножения, которые кроме операнда, указанного в команде, используют еще и второй, неявный операнд.
Из перечисленных сочетаний операндов наиболее часто употребляются регистр–память и память–регистр.
Способ адресации определяет, каким образом следует использовать информацию, размещенную в поле адреса команды.
Не во всех случаях в поле адреса команды помещается адрес операнда. Существует пять основных способов адресации операндов в командах.
а) Прямая – в этом случае в адресном поле располагается адрес операнда. Разновидность – прямая регистровая адресация, адресующая не ячейку памяти, а РОН (регистр общего назначения). Поле адреса регистра имеет в команде значительно меньшую длину, чем поле адреса памяти.
б) Непосредственная – в поле адреса команды располагается не адрес операнда, а сам операнд. Такой способ удобно использовать в командах с константами.
в) Косвенная – в поле адреса команды располагается адрес ячейки памяти, в которой хранится адрес операнда («адрес адреса»). Такой способ позволяет оперировать адресами как данными, что облегчает организацию циклов, обработку массивов данных и др. Его основной недостаток – потеря времени на двойное обращение к памяти – сначала за адресом, потом – за операндом. Разновидность – косвенно-регистровая адресация, при которой в поле команды размещается адрес РОН, хранящего адрес операнда. Этот способ, помимо преимущества обычной косвенной адресации, позволяет обращаться к большой памяти с помощью коротких команд и не требует двойного обращения к памяти (обращение к регистру занимает гораздо меньше времени, чем к памяти).
г) Относительная – адрес формируется как сумма двух слагаемых: базы, хранящейся в специальном регистре или в одном из РОН, и смещения, извлекаемого из поля адреса команды. Этот способ позволяет сократить длину команды (смещение может быть укороченным, правда в этом случае не вся память доступна в команде) и/или перемещать адресуемые массивы информации по памяти (изменяя базу). Разновидности – индексная и базово-индексная адресации. Индексная адресация предполагает наличие индексного регистра вместо базового. При каждом обращении содержимое индексного регистра автоматически модифицируется (обычно увеличивается или уменьшается на 1). Базово-индексная адресация формирует адрес операнда как сумму трех слагаемых: базы, индекса и смещения.
д) Безадресная – поле адреса в команде отсутствует, а адрес операнда или не имеет смысла для данной команды, или подразумевается по умолчанию. Часто безадресные команды подразумевают действия над содержимым аккумулятора. Характерно, что безадресные команды нельзя применить к другим регистрам или ячейкам памяти. Одной из разновидностей безадресного обращения является использование т.н. магазинной памяти или стека. Обращение к такой памяти напоминает обращение с магазином стрелкового оружия. Имеется фиксированная ячейка, называемая верхушкой стека. При чтении слово извлекается из верхушки, а все остальное содержимое «поднимается вверх» подобно патронам в магазине, так что в верхушке оказывается следующее по порядку слово. Одно слово нельзя прочитать из стека дважды. При записи новое слово помещается в верхушку стека, а все остальное содержимое «опускается вниз» на одну позицию. Таким образом, слово помещенное в стек первым, будет прочитано последним. Говорят, что стек поддерживает дисциплину LIFO – Last In First Out (последний пришел – первый ушел). Реже используется безадресная память типа очередь с дисциплиной FIFO – First In First Out (первый пришел – первый ушел).