logo search
Лекции препода / Конспект лекций ЭВМ

2.6. Операнды и режимы адресации операндов

Команды обычно выполняют операции над одним или двумя операнда­ми. Например, команда ADD прибавляет значение одного операнда к значению второго операнда и запоминает результат в одном из них. Коман­да инкремента INC прибавляет 1 к значению единственного операнда и сохраняет результат на месте операнда. Теперь нам нужно детально рас­смотреть, как команда определяет свои операнды, т.е. режимы адресации операндов.

Один операнд. Обратимся к команде, которая определяет единствен­ный операнд, например к команде INC. Обычно она применяется для инкремента указательного или индексного регистра при вычислении смещений, а также

- 16-битного РОНа в арифметических операциях. С такими операндами команда принимает очень простую однобайтную форму, показанную на рис. 2.8. Она имеет 3-битное поле reg, определяющее один из восьми 16-битных регистров. Кодирование регистров в поле reg показано в первых двух столбцах табл. 2.1.

Таблица 2.1 Кодирование регистров

16-битный регистр

8-битный регистр

000

AX

AL

001

CX

CL

010

DX

DL

011

BX

BL

100

SP

AH

101

BP

CH

110

SI

DH

111

DI

BH

Остальные 5 бит команды определяют операцию и называютсякодом операции (КОП). Например, у команды INC код операции равен 01000. На рис. 2.9 показана команда, которая производит инкремент содержимого регистра ВР. Такой способ адресации операнда иногда называется регист­ровым режимом. В табл. 2.2 показаны все режимы адресации операндов.

Таблица 2.2 Режимы адресации операндов

НЕПОСРЕДСТВЕННЫЙ

РЕГИСТРОВЫЙ

ПРЯМАЯ АДРЕСАЦИЯ ПАМЯТИ

КОСВЕННАЯ АДРЕСАЦИЯ ПАМЯТИ

Базовый регистр

Индексный регистр

Базовый регистр + индексный регистр

Базовый регистр + смещение

индексный регистр + смещение

Базовый регистр + индексный регистр + смещение

В наиболее общей форме команда INC может произвести инкремент содержимого любого РОНа, указательного или индексного регистра (8 или 16 бит) и любого байта или слова памяти. Эта форма длиной в два байта показана на рис. 2.10. Теперь поле КОП расщеплено на две части: семь бит его находятся в первом байте, а три - во втором. Код операции команды INC в такой форме равен 1111111 000. Однобитное поле w определяет длину операнда: если w = 0, операнда имеет 8 бит, а при w = 1 - 16 бит. Поле mod показывает, находится ли операнд в регистре или памяти. Если mod = 11, операнд содержится в регистре, а три остальные комбинации поля mod относятся к памяти. Когда операнд - в регистре, поле rпоказывает конкретный регистр; а если операнд - в памяти, это же поле определяет, где именно он находится (сокращение rобозначает регистр/память).

Вначале рассмотрим случай, когда операнд находится в регистре(mod = 11). Кодирование регистров в поле rпоказано в табл. 2.1. По существу, мы имеем второй вариант регистрового режима адресации операндов. На рис. 2.11 приведена команда инкремента содержимого регистра CL. Для доступа к 8-битному регистру требуется более длинная форма команды INC.

Теперь обратимся к случаю, когда операнд находится в памяти (mod = = 00, 0, 10). Этот режим иногда называется косвенной адресацией памяти, f так как операнд содержится в памяти, но смещение явно не указано. Вместо этого оно получается суммированием довольно странных на пер­вый взгляд значений. (Удобство такого режима мы пояснили в разд. 1.7.) Смещение равно сумме не более трех слагаемых: 16-битного значения (оно называется смещением в команде), содержимого индексного регистра (SI, DI или никакого), определенного в команде, и содержимого базового регистра (SP, ВР или никакого), указанного в команде. Поле rидентифи­цирует базовый и индексный регистры в соответствии с табл. 2.3, а поле mod определяет смещение в Команде (см. табл. 2.4). Образованный резуль­тат локализует операнд внутри сегмента. Операнд находится в текущем сегменте данных (но если в вычислении смещения участвует регистр ВР, операнд находится в текущем сегменте стека). Конечно, для образования 20-битного (24-битного в виртуальном режиме) адреса памяти потребуется еще одно сложение с привлечением сегментного регистра.

Таблица 2.3 Базовый и индексный регистры, определяемые полем rдля операндов в памяти (mod 11)

Поле r

Базовый регистр

Индексный регистр

000

BX

SI

001

BX

DI

010

BP

SI

011

BP

DI

100

НЕТ

SI

101

НЕТ

DI

110

BP

НЕТ

111

BX

НЕТ

Если mod = 00 и r/m ==110, см. примечание к табл. 2.4

Таблица 2.4 Смещение в команде, определяемые полем mod для операндов в памяти (mod 11)

mod

Смещение в команде

Пояснение

00

Нуль (16 бит)

01

8-битное содержимое следующего байта команды расширяется со знаком до 16 бит

Команда имеет дополнительный байт

10

16-битное содержимое двух следующих байт команды (сначала младший, а затем старший байты)

Команда имеет два дополнительных байта

Если mod = 00 и r/m = 110, то:

Табл 2.3 и 2.4 непременимы;

Команда содержит два дополнительных байта. В этих байтах находятся все смещения в сегменте (сначала младший, а затем старший байты)

В качестве примера рассмотрим команду, показанную на рис. 2.12. Поле кода операции содержит 1111111 000 и определяет команду INC. Поле w = 1 показывает длину операнда 16 бит. Поле mod = 01 и операнд, следовательно, находится в памяти; кроме того, смещение в команде из следую­щего байта необходимо расширить со знаком до 16 бит: 0000 0000 0101 1100.

Поле r= 100, поэтому со смещением в команде следует просуммировать содержимое регистра SI (пусть оно равно 1010 0000 1000 0110);

+1010 0000 1000 0110 (содержимое SI)

0000 0000 0101 1100 (смещение в команде)

1010 0000 1110 0010 (результат)

Так как в вычислениях не участвует регистр ВР, операнд находится в текущем сегменте данных. Предположим, что регистр DS содержит 1111 0000 1111 0000 и процессор работает в реальном режиме. Тогда адрес операнда в памяти равен:

+1111 0000 1111 0000 (сегмент)

1010 0000 1110 0010 (смещение в сегменте)

1111 1010 1111 1110 0010 (адрес памяти)

Длина операнда 16 бит(w = 1), поэтому им является содержимое двух байт с адресами 1111 1010 1111 1110 0010 (младший) и 1111 1010 1111 1110 0011 (старший).

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

командой однобайтный префикс, обозначающий сегментный регистр (рис. 2.13). На рис. 2.14 показана та же команда, что и на рис. 2.12, но теперь операнд находится в текущем дополнительном сегменте.

Мы рассмотрели задание смещения операнда в памяти с помощью базового и/или индексного регистров, но часто операнд находится в фиксированной ячейке одного из сегментов. В этом случае целесообразно определить все смещение непосредственно в команде. Такой режим адресации операндов называетсяпрямой адресацией памяти: смещение находится в двух байтах самой команды (конечно, "наоборот"). Как обычно, команда должна определить также код операции и сам факт прямой адресации памяти. Было бы удобно использовать для указания режима комбинацию бит в полях mod и r/т. К сожалению, все комбинации уже исчерпаны для косвенной адресации памяти и регистровой адресации, поэтому для нашей цели придется привлечь какую-то редко используемую комбинацию. Такой комбинацией оказалась mod = 00 и r= 110. Как пример, на рис. 2.15 показана команда, которая производит инкремент байта со смещением 0101 1010 1111 0000 в текущем сегменте данных.

Для прямой адресации пришлось пожертвовать косвенной адресацией через ВР (без индексного регистра и с нулевым смещением в команде), но ее можно реализовать, указав mod = 01 и введя дополнительный байт для нулевого смещения в команде.

Два операнда. Разобравшись с однооперандными командами, обратим­ся к командам, имеющим два операнда, например ADD. Мы уже говорили, что эта команда берет значение одного операнда, прибавляет его к значе­нию второго операнда и запоминает результат на месте любого операнда. Если разрешить нахождение обоих операндов в памяти, в команде потре­бовались бы поля mod и rдля каждого из них. Чтобы сократить длину команд, было решено, что, по крайней мере, один из операндов должен

быть в регистре. Тогда в команде потребуются поля mod и rтолько для одного операнда, а для другого достаточно поля reg (рис. 2.16).

Поле w показывает, являются операнды байтами (w = 0) или словами (w = 1). В команде появилось также новое поле d (приемник); если d = 0, результат запоминается в операнде, определяемом полями mod и r/т, a если d - 1 - в операнде, определяемом полем reg. Операнд, в котором запоминается результат, называется приемником, а другой операнд назы­вается источником.

В качестве примера рассмотрим команду ADD, показанную на рис. 2.17. Она имеет код операции 000000. Поле w = 0 показывает, что оба опе­ранда являются байтами. Определяемым полем reg операндом оказывает­ся регистр СН. Поле mod = 11 означает, что поля mod и rопределяют регистр, а поле rконкретизирует регистр BL. Поле d = 1 показывает запись результата в операнд, определяемый полем reg, т.е. в регистр СН. Следовательно, команда прибавляет содержимое регистра BL (источника) к содержимому регистра СН (приемника) и помещает результат в СН.

Одним из операндов в двухоперандной команде может быть констан­та, содержащаяся в самой команде как непосредственный операнд. Этим достигаются два преимущества: уменьшается требуемая память (не нужно хранить адрес данных и сами данные) и процессор быстрее получает данные.

Примером команды с непосредственным операндом служит командаMOV (переслать). Она часто применяется для загрузки константы в регистр. Здесь непосредственный операнд можно определить полем reg, и команда приобретает простую форму, показанную на рис. 2.18. Поле w по-прежнему задает длину операнда 8 (w = 0) или 16 (w = 1) бит; в первом случае непосредственный операнд занимает один байт в команде, а во втором — два байта. Как пример, на рис. 2.19 представлена команда, которая передает значение 1111 0000 0000 1111 в регистр DI.

Внесколько более сложной команде операнд-приемник определяется полямиmod и rвместо поля reg, поэтому в команде появляется допол­нительный байт (рис. 2.20). Показанная на рис. 2.21 команда передает значение 1111 0000 0000 1111 в слово, находящееся в сегменте данных со смещением из регистра DI.

Так как двух операндная команда имеет только одно полеw, оба операнда должны иметь длину 8 или 16 бит. Однако часто непосредствен­ные операнды являются небольшими числами и не требуют 16 бит. Это утверждение особенно справедливо для команд сложения, вычитания и сравнения, хотя для операндов логических команд оно обычно не выдер­живается. Следовательно, можно уменьшить размер команд с непосред­ственными операндами, если не отводить 16 бит для хранения небольших чисел. Поэтому в некоторых командах (сложение, вычитание и сравнение) введен бит s (s означает "с расширением знака"). Он занимает место бита d, так как в командах с непосредственными операндами возможно только одно направление. Поле s имеет смысл только для 16-битных операндов (w = 1) и показывает, содержатся ли в команде все 16 бит непосредственно­го операнда (s = 0) или только 8 бит (s = 1), которые должны расширяться со знаком до 16 бит для образования 16-битного операнда. Такая форма команды иллюстрируется рис. 2.22. Соответствующий пример показан на рис. 2.23. Здесь к содержимому слова в памяти прибавляется значение 0000 0000 0000 1111 и результат помещается в это же слово. Слово находит­ся в сегменте данных, а смещение его берется из регистра DI. Отметим, что благодаря биту s экономится один байт.