МИРЭА кафедра МОВС


Форматы команд и способы адресации

В этом разделе мы рассмотрим трансляцию предложений исходной программы УУМ/ДС Объектная программа COPY для УУМ в соответствующее им объектное представление Объектный код для программы, обращая особое внимание на обработку ассемблером различных командных форматов и способов адресации. Заметим, что предложение START задает теперь 0 в качестве начального адреса программы. Как будет сказано в следующем разделе, это является признаком перемещаемой программы. Однако процедура трансляции команд остается при этом такой же, как если бы программа действительно загружалась с адреса 0. Трансляция команд вида регистр-регистр, таких как CLEAR (строка 125) или СОМРК (строка 150), не представляет никаких новых проблем. Ассемблер должен просто преобразовать мнемонические коды операций в их машинное представление (используя ОРТАВ) и заменить мнемонические имена регистров на их числовые эквиваленты. Так же как и для команд других видов, это делается во время второго просмотра. Преобразование имен регистров в их числовые значения может делаться с помощью отдельной таблицы. Однако часто бывает удобно использовать для этих целей таблицу имен. Для этого в SYMTAB заранее заносятся имена регистров (АX и т. д.) и их значения (О, 1 и т.д.). Для трансляции большинства команд вида память-регистр используется относительный способ адресации (либо относительно счетчика команд, либо относительно базы). В любом случае ассемблер должен вычислить смещение, которое является составной частью объектной команды. Оно вычисляется так, чтобы после его сложения с регистром счетчика команд (PC) или базовым регистром (В) получить требуемый целевой адрес. Конечно, величина полученного смещения должна быть не слишком большой, чтобы поместиться в 12-разрядном поле команды. Это означает, что величина смещения должна находиться в диапазоне от 0 до 4095 (для адресации относительно базы) или в диапазоне от -2048 до +2047 (для адресации относительно счетчика команд). Если не подходит ни один из относительных способов адресации (из-за того что величина смещения слишком велика), следует использовать расширенный 4-байтовый командный формат (формат 4). Этот формат имеет 20-разрядное адресное поле, позволяющее хранить полный адрес. В этом случае никакого смещения не вычисляется. Например, в команде 15 0006 CLOOP + JSUB RDREC 4В101036 адрес команды равен 1036. Это полный адрес, который хранится в команде вместе с признаком, указывающим на использование расширенного командного формата (разряд е установлен в 1). Отметим, что программист должен с помощью префикса + сам указать команды, в которых используется расширенный командный формат (см. строку 15). Если нельзя применить ни один из способов относительной адресации и нет указания об использовании расширенного формата, то правильная трансляция команды невозможна. В этом случае ассемблер должен выдать сообщение об ошибке. Рассмотрим теперь детально, как вычисляется смещение для относительных способов адресации. По существу, ассемблер должен в обратном порядке выполнить те операции, которые выполняются при вычислении целевого адреса. Вам следует вспомнить, как это делается, посмотрев еще раз разделе Структура УУМ/ДС. Типичным примером команды, в которой используется адресация относительно счетчика команд, является команда 10 0000 FIRST STL RETADR 17202D Во время выполнения команд в УУМ/ДС (как и в большинстве ЭВМ) счетчик команд продвигается вперед после выборки очередной команды (но до ее выполнения). Таким образом, во время выполнения команды STL регистр РС будет содержать адрес следующей команды (в данном случае 0003). Из листинга мы также видим, что метка RETADR (строка 95) имеет адрес 0030. (Ассемблер, естественно может получить эту информацию из SYMTAB.) Необходимое нам смещение вычисляется как 30 - 3 = 2D. Во время выполнения этой команды ее целевой адрес будет вычисляться как (PC) + disp, что и даст нужный нам результат (0030). Обратите внимание, что разряд р установлен в 1, что является признаком адресации относительно счетчика команд. Таким образом, два последних байта машинной команды содержат код 202. Тот факт, что в данной команде не используется ни косвенная адресация, ни непосредственное задание операнда, указывается установкой 1 в разряды n и i. Поэтому первый байт машинной команды содержит код 17, а не 14 (см. описание значений разрядов-признаков на рисунке Примеры команд и способов адресации УУМ/ДС Другим примером адресации относительно сметчика команд может служить предложение 40 0017 J CLOOP 3F2FEC Здесь адрес операнда равен 0006. Во время выполнения команды регистр PC будет иметь значение 0001А. Величина смещения вычисляется как 6 - 1A = -14. Taк как это отрицательное число, то оно будет представлено в дополнительном коде. В машиной команде для поля смещения отводится 12 разрядов. Поэтому смещение будет записано как FEC. Аналогичным образом вычисляется смещение для адресации относительно базового регистра. Основное отличие заключается в том, что ассемблеру известно значение счетчика команд на момент выполнения программ, в то время как значение базового регистра определяется программистом. Поэтому программист должен сообщить ассемблеру значение базового регистра на момент выполнения программы. В нашем примере это делается с помощью директивы ассемблера BASE. Данное предложение (строка 13) сообщает ассемблеру, что базовый регистр будет содержать адрес метки LENGTH. Предшествующая команда LDB #LENGTH загружает это значение в регистр во время работы программы. До тех пор, пока ассемблер не встретит другую команду BASE, он будет полагать, что значение базового регистра не меняется. Возможно, что в последующих фрагментах программы будет желательно использовать регистр В для других целей (например, для временного хранения некоторого значения). В этом случае программист должен использовать другую директиву ассемблера (например, NOBASE), для того, чтобы сообщить ему, что содержимое базового регистра теперь нельзя использовать для базирования. Важно уяснить, что BASE и NOBASE это директивы ассемблера, которые не переводятся в выполняемые машинные команды. Для загрузки базового регистра требуемым значением программист должен предусмотреть в программе соответствующие команды. Если этого не сделать, то целевой адрес будет вычисляться неверно. Типичным примером команды, в которой используется адресация относительно базы, является команда 160 104Е STCH BUFFER,X 57С003 В соответствии с предложением BASE регистр В будет содержать во время исполнения программы значение 0030 (адрес LENGTH). Адрес метки BUFFER равен 0036. Таким образом, смещение определяется как 36 - 33 = 3. Заметим, что в машинном представлении команды оба разряда х и b установлены в 1, что является признаком адресации относительно базы с индексированием. Другим примером может служить команда STX LENGTH (строка 175). Здесь смещение равно 0. Отметим различия в трансляции предложений в строках 20 и 175. В строке 20 для предложения LDA LENGTH использована адресация относительно счетчика команд. В строке 175 для STX LENGTH использована адресация относительно базы. (Если вы вычислите для этой команды смещение относительно счетчика команд, то убедитесь, что его значение слишком велико для 12-разрядного поля.) Для предложения в строке 20 можно использовать оба способа адресации. Однако наш ассемблер вначале делает попытку использовать адресацию относительно счетчика команд. Выбор приоритета того или иного способа адресации достаточно произволен и устанавливается разработчиком ассемблера. Трансляция команд, в которых используются непосредственные операнды, проще, поскольку в них не нужна организация ссылок на оперативную память. Все, что требуется, это преобразовать операнд во внутреннее представление и занести его в команду. Типичным примером команды, в которой используется непосредственный операнд, является команда 55 0020 LDA #3 010003 Операнд 003 хранится непосредственно в команде. Разряд i установлен в 1, что является признаком непосредственного операнда. Другим примером может служить команда 133 103С +LDT #4096 75101000 В данном случае операнд (4090) слишком велик для 12-разрядного поля и поэтому используется расширенный командный формат. (Если бы операнд был велик и для 20-разрядного поля, то мы не могли бы задать его непосредственно в команде.) Другой способ использования непосредственного операнда показан в команде 12 0003 LDB #LENGTH 69202D В этом предложении непосредственный операнд задан именем LENGTH. Поскольку его значением является адрес, то в результате выполнения этой команды в регистр В будет загружен адрес, назначенный переменной LENGTH. Заметим, что в данном случае используется комбинация адресации относительно счетчика команд с непосредственным заданием операнда. Хотя на первый взгляд такая адресация может выглядеть не совсем обычной, тем не менее она не противоречит предыдущим рассуждениям. Дело в том, что в общем случае всегда вначале вычисляется целевой адрес, и если в команде установлен признак непосредственного операнда, то этот адрес (а не содержимое по этому адресу) будет использован в качестве операнда. (В предложении LDA в строке 55 разряды х, b и р установлены в 0. Таким образом, целевой адрес просто совпадает со смещением 003.) Ассемблирование команд, использующих косвенную адресацию, (фактически не представляет ничего нового. Для того чтобы получить требуемый целевой адрес, вначале обычным образом вычисляется смещение. Затем в разряд n генерируемой команды устанавливается признак косвенной адресации. Примером использования адресации относительно счетчика команд в комбинации с косвенной адресацией является предложение в строке 70.