Поскольку вычисление для операнда адреса, состоящего из базы и индекса, встречается довольно часто, среди способов адресации 8088 есть такие, что позволяют автоматически производить идексирующее сложение. Вместо выполнения всех вычислений, программа может определить только величину 2*I и поместить ее в регистр BX. Команда
INC [OPND + BX]
вычисляет исполнительный адрес через сложение адреса базы OPND со значением индекса в BX. Этой командой достигается тот же самый результат что и в предыдущем случае, но меньшим числом команд. Обратите внимание, что в этой команде ассемблеру не требуется подсказка WORD PTR, потому что ассемблер уже знает, что OPND является переменной типа WORD. Оператор PTR требуется только в тех случаях, когда ассемблер не может определить тип операнда. Любой из четырех адресных регистров может быть использован в качестве индексапри базе. Фиг. 3.2 показывает возможные способы адресации черезбазу и индекс. Вы видите, что ассемблер допускает несколько способов записи операции адресации. В группе, состоящей из пяти команд на Фиг. 3.2, во всех командах адрес базы OPND складывается с указанным рядом индексным регистром. Надо отметить, что в команде, содержащей базисный адрес, регистр не обязательно должен содержать именно значение индекса. Действительно, поскольку BX называется базисным регистром, кажется разумным воспользоваться противоположной конфигурацией. В качестве примера предположим, что программа использует множество разных векторов с одинаковой длиной и размером элементов. Такую структуру может иметь, например, классный журнал, в котором векторам соответствуют наборы оценок за каждую контрольную работу. Программа, вычисляющая оценку пятого ученика в классе по I-й работе будет иметь уже известное значение индекса (5) а базу (вектор данной контрольной работы) - вычисляемую в ходе выполнения программы. Индексный регистр может содержать как адрес базы вектора, так и значение индекса в векторе. Поскольку константное значение в команде может оказаться и базой и индексом (или вовсе чем-нибудь известным только программисту), то это значение называют смещением. Оно соответствует расстояню или смещению от адреса в регистре до исполнительного адреса, по которому происходит обращение.
|
3.7. База + индекс + смещение
Программа может также комбинировать вычисляемый адрес базы с вычисляемым индексом. Как показано на Фиг.3.2, программа может использовать режим адресации с двумя разными адресными регистрами. Для формирования исполнительного адреса в команде могут сочетаться любой из регистров базы (BX и BP) с любым из индексных регистров (SI и DI). В программе может быть также указано смещение, добавляемое к сумме значений этих двух регистров. Этот способ адресации обладает максимальной гибкостью, так как позволяет вычислять вовремя выполнения программы и адрес базы, и индексное значение. Такая возможность не всегда требуется, но доступна в любой момент. Пример с классным журналом демонстрирует случай, когда программа может вычислять и адрес базы, и индекс вектора. Для того, чтобы определить отметку I-го ученика за J-ю контрольную, потребовалось бы установить адрес базы на J-й вектор и индексировать его по I-му элементу. На рис.3.3 приведена сводка восьми различных способов адресации, возможных в микропроцессоре 8088. В команде могут использоваться любые из четырех адресных регистров и смещение либо комбинация базисного регистра и индексного вместе со смещением. Смысл колонки, обозначенной R/M, будет объяснен позже.
|
R/M | Адрес операнда |
[BX + SI + СМЕЩЕНИЕ] | |
[BX + DI + СМЕЩЕНИЕ] | |
[BP + SI + СМЕЩЕНИЕ] | |
[BP + DI + СМЕЩЕНИЕ] | |
[SI + СМЕЩЕНИЕ] | |
[DI + СМЕЩЕНИЕ] | |
[BP + СМЕЩЕНИЕ] | |
[BX + СМЕЩЕНИЕ] |
Фиг. 3.3 Способы адресации 8088
В наборе команд 8088 поле смещения для адресации оптимизировано таким образом, чтобы минимизировать количество требуемых байт. Команда может не содержать поле смещения, когда смещение равно нулю. Если смещение находится в диапазоне от -127 до 127, то для него достаточно одного байта. Когда же для его обозначения требуется полное 16-битовое поле адреса, то поле смещения будет занимать два байта. Таким образом, поле смещения может по необходимости иметь длину 0, 1 или 2 байта. Когда оно имеет длину один байт, двоичное число перед форимроваием адереса получает распостранение знака. Это означает, что процессор перед выполнением сложения помещает старший бит смещения в старшие 8 бит 16-битового значения. Это позволяет представлять отрицательные смещения в одном байте. Самое лучшее здесь то, что ассемблер сам определяет нужную длину и выбирает правильную и наиболее короткую команду для выполнения этой работы. Но не смотря даже на все эти возможности адресации, набор команд 8088 допускает только по одному операнду памяти в одной команде. Двухоперандная команда ADD позволяет складывать либо регистр с ячейкой памяти, либо два регистра. В одной команде нельзя сложить две ячейки памяти. Это и означает, что команда содержит только один адрес памяти.
|
Байт MOD R-M
Как же адресная информация передается микропроцессору в машинном языке? 8088 использует почти для всех операций адресации байт MOD-R/M (байт режима адресации и регистра/модификатора - прим. перев.). Фиг.3.4 показывает формат этого байта команды. Байт MOD-R/M следует за байтом кода операции и определяет один операнд памяти команды 8088. Этот байт может вместо ячейки памяти указывать и регистр. Такое единство структуры позволяет реализовать все возможности адресации операндов.
Режим | Адрес операнда |
DISP=0, нет байтов смещения | |
-128<DISP<127, однобайтовое смещение | |
-32768<DISP<32767, двухбайтовое смещение | |
В поле r/m - регистр, а не адрес |
Фиг. 3.4 Байт режима адресации и регистра-модификатора
Первые два бита байта MOD-R/M определяют выбранный способ адресации. Эти два бита определяют число байт смещения, которые следуют за байтом MOD-R/M - ни одного, один или два. Последние 3 бита байта MOD-R/M определяют вид адреса - одну из восьми комбинаций базисных и индексных регистров. Это поле называется полем R/M - полем регистра/модификатора. Это те самые 3 бита из колноки R/M на Фиг.3.3, где показаны возможные комбинации при адресации. Значение оставшихся 3-х бит в середине байта MOD-R/M зависят от конкретной команды. Для команды с двумя операндами, вроде ADD, это поле указывает регистр, являющийся вторым операндом. Для команды с одним операндом, как INC, эти три бита обычно составляют часть самого кода операции. 8088 не знает, что имеет дело с командой INC, пока не расшифрует средние три бита байта MOD-R/M. Этот же байт используется еще в паре специальных случаев. Если в команде определен регистр, а не адрес памяти, то в поле режима помещается код 11B, чтобы сообщить микропроцессору, что поле R/M содержит код регистра, а не адрес памяти. Наконец, вы возможно заметили, что в механизме работы с байтом MOD-R/M не предусмотрена прямая адресация. 8088 рассматривает как прямую адресацию случай типа [BP + СМЕЩЕНИЕ] при нулевом смещении. В этом случае поле смещения имеет длину два байта, и в вычислении адреса не участвует ни один регистр. Из-за этого особого случая доступ к ячейке памяти, на которую указывает регистр BP, в машинном коде требуется однобайтовое поле смещения с нулевым значением. Использование в той же ситуации регистров BX, SI и DI не требует байта смещения. В следующем пункте будет показано еще одно различие между адресацией через регистры BP и BX.
Физическая адресация
Все, что до сих пор говорилось об адресации, относится к генерации так называемого смещения (offset) адреса. Смещение имеет 16-битовое значение. 8088 сегментирует память таким образом, что можно адресоваться к памяти большей чем 64K. В этом пункте булет показан способ сегментации 8088. Поскольку размер слова в микропроцессоре 8088 равен 16 бит, для него естественно генерировать адреса в 16бит длиной. Это делает доступными дляпрямой адрессации 2**16 элементов или 65 535 байт памяти. Однако для некоторых программ 64K ячеек памяти недостаточно. Поэтому фирма INTEL сконструировала 8088 для адресации 2**20 байт или одного мегабайта памяти. Для получения 20-битовой адресации требуется еще четыре бита к имеющимся 16-ти. Добавочные 4 бита адресной информации берутся из сегментных регистров. Сегментные регистры сами имеют размер 16 бит. 8088 комбинирует 16-битовый адрес смещения и 16-битовый регистр сегмента как показано на Фиг.3.5. Процессор дополняет сегментный регистр 4-мя нулевыми битами, что составляет вместе полное 20-битовое значение. К расширенному значению сегмента процессор добавляет адрес смещения, определяемый через вычисление адреса. 20-битовый результат является указателем на исполнительный адрес.
Сегмент * 16 + Смещение = 20-битовый адрес
Фиг.3.5 Вычисление адреса с сегментом и смещением
Каждая обращающаяся к памяти команда может сформировать только 16-битовый адрес операнда. В действительности процессор применяет этот адрес внутри определенного сегмента. Фиг. 3.6 иллюстриирует такой способ применения сегментации.
Сегмент | смещение |
xxxx xxxx 0000 | |
.... | |
FFFF | |
yyyy yyyy 0000 | |
.... | |
FFFF |
Фиг.3.6 Сегментация.
Начальный адрес сегмента всегда имеет нули в младших четырех битах. Адрес с этим свойством имеет каждая шестнадцатая ячейка памяти. Конструируя расположение данных в своей программе помните, что сегмент всегда должен приходиться на такую 16-битовую границу. Эти границы называются также границами параграфов
Сегментные регистры
INTEL 8088 имеет четыре сегментных регистра: CS,DS,SS и ES - для кодового, данных-, стекового и дополнительного сегментов соответственно. Это их обычное использование, но применение этих регистров может именяться в соответствии с потребностями программы.
8088 использует регистр сегмента программы для идентификации того сегмента, который содержит выполняемую вданный момент программу. В сочетании с указателем команд регистр CS используется для указания текущей команды. Каждая выполняемая команда находится в ячейке, на которую указывает пара регистров CS:IP. Комбинация сегментного регистра с регистром смещения для указания физического адреса записывается в виде сегмент:смещение, например, CS:IP. Значение сегмента стоит перед двоеточием, смещение - после. Такая нотация используется и для регистров, и для абсолютных адресов. Вы можете писать такие адреса как CS:100, DS:BX, 570:100, или 630:DI.
Регистр сегмента данных (DS) процессор использует для обычного >доступа к данным. Схемы адресации для операндов, которые мы рассматривали впредыдущем пункте, дают 16-битовое смещение, и в большинстве случаев для формирования исполнительного адреса процессор комбинирует это смещение с ргеистром DS.
Регистр сегмента стека указывает на системный стек. Команды PUSH, POP, CALL и RET управляют данными в стеке в позиции по адресу SS:SP. Регистр SP - указатель стека - служит для определения смещения в стеке. Кроме того, сегмент стека подразумевается по умолчанию при адресации с использованиемрегистра BP. Это дает доступ к данным в стеке с использованием в качестве указателя регистра BP. В следующей главе есть пункт о стековых операциях, который демонстрирует, каким образом адресация через BP упрощает связь с данными в стеке.
Наконец, регистр дополнительного сегмента используется 8088 для доступа к данным, когда требуется более одного сенмента. Обычной операцией такого рода является копирование данных из одной области памяти в другую. Между областями, находящимися не внутри одного и того же блока памяти размером 64К, невозможно произвести обмен данными, используя единственный сегментный регистр. Имея в распоряжении дополнительный сегментный регистр, программа, как показано на Фиг. 3.7, может указать одновременно исходный и целевой сегменты. Регистр DS указывает область исходных данных, а регистр ES - сегмент назначения.
Копировать отсюда DS:источник ==> сюда ES:приемник
Фиг.3.7 Копирование из сегмента в сегмент
Для передачи данных существуют специальные строковые команды, которые автоматически используют регистры DS и ES для указания исходного и целевого регистров.