Структура команд. Исполнительные адреса




Машинные команды ПК занимают от 1 до 6 байтов.

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

Команды могут иметь от 0 до 3 операндов, у большинства команд ­один или два операнда. Размер операндов - байт или слово (редко ­двойное слово). Операнд может быть указан в самой команде (это т.н. непосредственный операнд), либо может находиться в одном из регистров ПК и тогда в команде указывается этот регистр, либо может находиться в ячейке памяти и тогда в команде тем или иным способом указывается ад­рес этой ячейки. Некоторые команды требуют, чтобы операнд находился в фиксированном месте (например, в регистре AX), тогда операнд явно не указывается в команде. Результат выполнения команды помещается в ре­гистр или ячейку памяти, из которого (которой), как правило, берется первый операнд. Например, большинство команд с двумя операндами реали­зуют действие

op1:= op1 _ op2

где op1 - регистр или ячейка, а op2 - непосредственный операнд, ре­гистр или ячейка.

Адрес операнда разрешено модифицировать по одному или двум регист­рам. В первом случае в качестве регистра-модификатора разрешено ис­пользовать регистр BX, BP, SI или DI (и никакой иной). Во втором слу­чае один из модификаторов обязан быть регистром BX или BP, а другой -

регистром SI или DI; одновременная модификация по BX и BP или SI и DI недопустима. Регистры BX и BP обычно используются для хранения базы (начального адреса) некоторого участка памяти (скажем, массива) и по­тому называются базовыми регистрами, а регистры SI и DI часто содержат индексы элементов массива и потому называются индексными регистрами. Однако такое распределение ролей необязательно, и, например, в SI мо­жет находиться база массива, а в BX - индекс элемента массива.

В MASM адреса в командах записываются в виде одной из следующих конструкции:

A, A[M] или A[M1][M2],

где A - адрес, M - регистр BX, BP, SI или DI, M1 - регистр BX или BP, а M2 - регистр SI или DI. Во второрм и третьем варианте A может отсут­ствовать, в этом случае считается, что A=0.

При выполнении команды процессор прежде всего вычисляет т.н. ис­полнительный (эффективный) адрес - как сумму адреса, заданного в ко­манде, и текущих значений указанных регистров-модификаторов, причем все эти величины рассматриваются как неотрицательные и суммирование

ведется по модулю 2^16 ([r] означает содержимое регистра r):

A: Aисп = A

A[M]: Aисп = A+[M] (mod 2^16)

A[M1][M2]: Aисп = A+[M1]+[M2] (mod 2^16)

Полученный таким образом 16-разрядный адрес определяет т.н. смеще­ние - адрес, отсчитанный от начала некоторого сегмента (области) памя­ти. Перед обращением к памяти процессор еще добавляет к смещению на­чальный адрес этого сегмента (он хранится в некотором сегментном реги­стре), в результате чего получается окончательный 20-разрядный ад­рес, по которому и происходит реальное обращение к памяти (см. 1.4).

Форматы команд

В ПК форматы машинных команд достаточно разнообразны. Для примера приведем лишь основные форматы команд с двумя операндами.

1) Формат "регистр-регистр" (2байта):

------------- ----------------

| КОП |d|w| | 11 |reg1|reg2|

------------- ----------------

7 2 1 0 7 6 5 3 2 0

Команды этого формата описывают обычно действие reg1:=reg1_reg2 или

reg2:=reg2_reg1. Поле КОП первого байта указывает на операцию (_), ко­торую надо выполнить. Бит w определяет размер операндов, а бит d ука­зывает, в какой из регистров записывается результат:

w = 1 - слова d = 1 - reg1:=reg1_reg2

= 0 - байты = 0 - reg2:=reg2_reg1

Во втором байте два левых бита фиксированы (для данного формата), а трехбитовые поля reg1 и reg2 указывают на регистры, участвующие в опе­рации, согласно следующей таблице:

reg w=1 w=0 reg w=1 w=0 ----------------- ----------------­

000 AX AL 100 SP AH

001 CX CL 101 BP CH

010 DX DL 110 SI DH

011 BX BL 111 DI BH

2) Формат "регистр-память" (2-4 байта):

------------- ------------- -------------------

| КОП |d|w| |mod|reg|mem| |адрес (0-2 байта)|

------------- ------------- -------------------

Эти команды описывают операции reg:=reg_mem или mem:=mem_reg. Бит w первого байта определяет размер операндов (см. выше), а бит d указыва­ет, куда записывается результат: в регистр (d=1) или в ячейку памяти (d=0). Трехбитовое поле reg второго байта указывает операнд-регистр (см. выше), двухбитовое поле mod определяет, сколько байтов в команде занимает операнд-адрес (00 - 0 байтов, 01 - 1 байт, 10 - 2 байта), а трехбитовое поле mem указывает способ модификации этого адреса. В сле­дующей таблице указаны правила вычисления исполнительного адреса в за­висимости от значений полей mod и mem (a8 - адрес размером в байт, a16

- адрес размером в слово):

mem \ mod | 00 01 10

------------------------------------------------------­000 | [BX]+[SI] [BX]+[SI]+a8 [BX]+[SI]+a16

001 | [BX]+[DI] [BX]+[DI]+a8 [BX]+[DI]+a16

010 | [BP]+[SI] [BP]+[SI]+a8 [BP]+[SI]+a16

011 | [BP]+[DI] [BP]+[DI]+a8 [BP]+[DI]+a16

100 | [SI] [SI]+a8 [SI]+a16

101 | [DI] [DI]+a8 [DI]+a16

110 | a16 [BP]+a8 [BP]+a16

111 | [BX] [BX]+a8 [BX]+a16

Замечания. Если в команде не задан адрес, то он считается нулевым. Если адрес задан в виде байта (a8), то он автоматически расширяется со знаком до слова (a16). Случай mod=00 и mem=110 указывает на отсутствие регистров-модификаторов, при этом адрес должет иметь размер слова (ад­ресное выражение [BP] ассемблер транслирует в mod=01 и mem=110 при a8=0). Случай mod=11 соответствует формату "регистр-регистр".

3) Формат "регистр-непосредственный операнд" (3-4 байта): ----------- ------------- --------------------------

| КОП |s|w| |11|КОП"|reg| |непосред.операнд (1-2 б)|

----------- ------------- --------------------------

Команды этого формата описывают операции reg:=reg_immed (immed - не­посредственный операнд). Бит w указывает на размер операндов, а поле reg - на регистр-операнд (см. выше). Поле КОП в первом байте определя­ет лишь класс операции (например, класс сложения), уточняет же опера­цию поле КОП" из второго байта. Непосредственный операнд может зани­мать 1 или 2 байта - в зависимости от значения бита w, при этом опе­ранд-слово записывается в команде в "перевернутом" виде. Ради экономии памяти в ПК предусмотрен случай, когда в операции над словами непос­редственный операнд может быть задан байтом (на этот случай указывает 1 в бите s при w=1), и тогда перед выполнением операции байт автомати­чески расширяется (со знаком) до слова.

4) Формат "память-непосредственный операнд" (3-6 байтов):

----------- -------------- -------------- ------------------

| КОП |s|w| |mod|КОП"|mem| |адрес (0-2б)| |непоср.оп (1-2б)|

----------- -------------- -------------- ------------------

Команды этого формата описывают операции типа mem:=mem_immed. Смысл всех полей - тот же, что и в предыдущих форматах.

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

Запись команд в MASM

Из сказанного ясно, что одна и та же операция в зависимости от ти­пов операдов записывается в виде различных машинных команд: например, в ПК имеется 28 команд пересылки байтов и слов. В то же время в MASM

все эти "родственные" команды записываются единообразно: например, все команды пересылки имеют одну и ту же символьную форму записи:

MOV op1,op2 (op1:=op2)

Анализируя типы операндов, ассемблер сам выбирает подходящую машинную команду.

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

метка: мнемокод операнды;комментарий

Метка с двоеточием, а также точка с запятой и комментарий могут отсут­ствовать. Метка играет роль имени команды, ее можно использовать в ко­мандах перехода на данную команду. Комментарий не влияет на смысл ко­манды, а лишь поясняет ее.

Мнемонические названия операций полностью перечислены в главе 2. Операнды, если есть, перечисляются через запятую. Основные правила

записи операндов следующие.

Регистры указываются своими именами, например:

MOV AX,SI;оба операнда - регистры

Непосредственные операнды задаются константными выражениями (их значениями являются константы-числа), например:

MOV BH,5;5 - непосредственный операнд

MOV DI,SIZE X;SIZE X (число байтов, занимаемых перемен­;ной X) - непосредственный операнд

Адреса описываются адресными выражениями (например, именами пере­менных), которые могут быть модифицированы по одному или двум регист­рам; например, в следующих командах первые операнды задают адреса:

MOV X,AH

MOV X[BX][DI],5

MOV [BX],CL

При записи команд в символьной форме необходимо внимательно сле­дить за правильным указанием типа (размера) операндов, чтобы не было ошибок. Тип обычно определяется по внешнему виду одного из них, напри­мер:

MOV AH,5;пересылка байта, т.к. AH - байтовый регистр

MOV AX,5;пересылка слова, т.к. AX - 16-битовый регистр

;(операнд 5 может быть байтом и словом, по нему;нельзя определить размер пересылаемой величины)

MOV [BX],300;пересылка слова, т.к. число 300 не может быть;байтом

Если по внешнему виду можно однозначно определить тип обоих опе­рандов, тогда эти типы должны совпадать, иначе ассемблер зафиксирует ошибку. Примеры:

MOV DS,AX;оба операнда имеют размер слова

MOV CX,BH;ошибка: регистры CX и BH имеют разные размеры

MOV DL,300;ошибка: DL - байтовый регистр, а число 300 не;может быть байтом

Возможны ситуации, когда по внешнему виду операндов нельзя опреде­лить тип ни одного из них, как, например, в команде

MOV [BX],5

Здесь число 5 может быть и байтом, и словом, а адрес из регистра BX может указывать и на байт памяти, и на слово. В подобных ситуациях ас­семблер фиксирует ошибку. Чтобы избежать ее, надо уточнить тип одного из операндов с помощью оператора с названием PTR:

MOV BYTE PTR [BX],5;пересылка байта

MOV WORD PTR [BX],5;пересылка слова

(Операторы - это разновидность выражений языка MASM, аналогичные функ­циям.)

Оператор PTR необходим и в том случае, когда надо изменить тип, предписанный имени при его описании. Если, например, X описано как имя переменной размером в слово:

X DW 999

и если надо записать в байтовый регистр AH значение только первого байта этого слова, тогда воспользоваться командой

MOV AH,X

нельзя, т.к. ее операнды имеют разный размер. Эту команду следует за­писать несколько иначе:

MOV AH,BYTE PTR X

Здесь конструкция BYTE PTR X означает адрес X, но уже рассматриваемый не как адрес слова, а как адрес байта. (Напомним, что с одного и того же адреса может начинаться байт, слово и двойное слово; оператор PTR

уточняет, ячейку какого размера мы имеем в виду.)

И еще одно замечание. Если в символьной команде, оперирующей со словами, указан непосредственный операнд размером в байт, как, напри­мер, в команде

MOV AX,80h

то возникает некоторая неоднозначность: что будет записано в регистр AX - число 0080h (+128) или 0FF80h (-128)? В подобных ситуациях ассем­блер формирует машинную команду, где операнд-байт расширен до слова, причем расширение происходит со знаком, если операнд был записан как отрицательное число, и без знака в остальных случаях. Например:

MOV AX,-128; => MOV AX,0FF80h (A:=-128)

MOV AX,128; => MOV AX,0080h (A:=+128) MOV AX,80h; => MOV AX,0080h (A:=+128)

 

СЕГМЕНТИРОВНИЕ



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2020-04-01 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: