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


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

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



В этом разделе мы рассмотрим трансляцию предложений исходной программы УУМ/ДС (рис.2.5) в соответствующее им объектное представление (рис.2.6), обращая особое внимание на обработку ассемблером различных командных форматов и способов адресации. Заметим, что предложение START задает теперь 0 в качестве начального адреса программы. Как будет сказано в следующем разделе, это является признаком перемещаемой программы. Однако процедура трансляции команд остается при этом такой же, как если бы программа действительно загружалась с адреса 0.

Трансляция команд вида регистр-регистр, таких как CLEAR (строка 125) или СОМРК (строка 150), не представляет никаких новых проблем. Ассемблер должен просто преобразовать мнемонические коды операций в их машинное представление (используя ОРТАВ) и заменить мнемонические имена регистров на их числовые эквиваленты. Так же как и для команд других видов, это делается во время второго просмотра. Преобразование имен регистров в их числовые значения может делаться с помощью отдельной таблицы. Однако часто бывает удобно использовать для этих целей таблицу имен. Для этого в SYMTAB заранее заносятся имена регистров (АX и т. д.) и их значения (О, 1 и т.д.).

 

Строка Адрес Исходное предложение Объектный код

5 0000 COPY START 0

10 0000 FIRST STL RETADR 17202D

12 0003 LDB #LENGTH 69202D

13 BASE LENGTH

15 0006 CLOOP +JSUB RDREC 4B101036

20 000A LDA LENGTH 032026

25 000D COMP #0 290000

30 0010 JEQ ENDFIL 332007

35 0013 +JSUB WRREC 4B10105D

40 0017 J CLOOP 3F2FEC

45 001A ENDFIL LDA EOF 032010

50 001D STA BUFFER 0F2016

55 0020 LDA #3 010003

60 0023 STA LENGTH 0F200D

65 0026 +JSUB WRREC 4B10105D

70 002A J @RETADR 3E2003

80 002D EOF BYTE C"EOF" 454F46

95 0030 RETADR RESW 1

100 0033 LENGTH RESW 1

105 0036 BUFFER RESB 4096

110 *

115 * ПОДПРОГРАММА ВВОДА ЗАПИСИ НА БУФЕР

120 *

125 1036 RDREC CLEAR X B410

130 1038 CLEAR A B400

132 103A CLEAR S B440

133 103C +LDT #4096 75101000

135 1040 RLOOP TD INPUT E32019

140 1043 JEQ RLOOP 332FFA

145 1046 RD INPUT DB2013

150 1049 COMPR A,S A004

155 104B JEQ EXIT 332008

160 104E STCH BUFFER,X 57C003

165 1051 TIXR T B850

170 1053 JLT RLOOP 3B2FEA

175 1056 EXIT STX LENGTH 134000

180 1059 RSUB 4F0000

185 105C INPUT BYTE X"F1" F1

195 *

200 * ПОДПРОГРАММА ВЫВОДА ЗАПИСИ ИЗ БУФЕРА

205 *

210 105D WRREC CLEAR X B410

212 105F LDT LENGTH 774000

215 1062 WLOOP TD OUTPUT E32011

220 1065 JEQ WLOOP 332FFA

225 1068 LDCH BUFFER,X 53C003

230 106B WD OUTPUT DF2008

235 106E TIXR T B850

240 1070 JLT WLOOP 3B2FEF

245 1073 RSUB 4F0000

250 1076 OUTPUT BYTE X"05" 05

255 END FIRST

 

Рис.2.6 Объектный код для программы на рис.2.5.

 

Для трансляции большинства команд вида память-регистр используется относительный способ адресации (либо относительно счетчика команд, либо относительно базы). В любом случае ассемблер должен вычислить смещение, которое является составной частью объектной команды. Оно вычисляется так, чтобы после его сложения с регистром счетчика команд (PC) или базовым регистром (В) получить требуемый целевой адрес. Конечно, величина полученного смещения должна быть не слишком большой, чтобы поместиться в 12-разрядном поле команды. Это означает, что величина смещения должна находиться в диапазоне от 0 до 4095 (для адресации относительно базы) или в диапазоне от -2048 до +2047 (для адресации относительно счетчика команд).

Если не подходит ни один из относительных способов адресации (из-за того что величина смещения слишком велика), следует использовать расширенный 4-байтовый командный формат (формат 4). Этот формат имеет 20-разрядное адресное поле, позволяющее хранить полный адрес. В этом случае никакого смещения не вычисляется. Например, в команде

15 0006 CLOOP + JSUB RDREC 4В101036

адрес команды равен 1036. Это полный адрес, который хранится в команде вместе с признаком, указывающим на использование расширенного командного формата (разряд е установлен в 1).

Отметим, что программист должен с помощью префикса + сам указать команды, в которых используется расширенный командный формат (см. строку 15). Если нельзя применить ни один из способов относительной адресации и нет указания об использовании расширенного формата, то правильная трансляция команды невозможна. В этом случае ассемблер должен выдать сообщение об ошибке.

Рассмотрим теперь детально, как вычисляется смещение для относительных способов адресации. По существу, ассемблер должен в обратном порядке выполнить те операции, которые выполняются при вычислении целевого адреса. Вам следует вспомнить, как это делается, посмотрев еще раз разд. 1.3.2. Типичным примером команды, в которой используется адресация относительно счетчика команд, является команда

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 (см. описание значений разрядов-признаков на рис.1.1 в разд.1.3.2).

Другим примером адресации относительно сметчика команд может служить предложение

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.

Перемещение программ

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

Программа, которую мы рассмотрели в разд. 2.1, представляет собой пример абсолютной программы (или абсолютного ассемблирования). Для того чтобы она правильно выполнялась, ее необходимо загрузить с адреса 1000 (т. е. с адреса, назначенного при ассемблировании). Чтобы убедиться в этом, рассмотрим команду

55 101В LDA THREE 00102D

из программы, представленной на рис.2.2. В объектной программе (рис. 2.3) этому предложению соответствует команда 001020, которая обеспечивает загрузку содержимого оперативной памяти по адресу 102D в регистр А. Предположим, что мы попытались загрузить и выполнить эту программу, с адреса 2000 (вместо 1000). В этом случае адрес 102D не будет содержать ожидаемого значения. Скорее всего данный адрес будет принадлежать какой-либо другой пользовательской программе.

Очевидно, для того чтобы программа могла правильно работать, начиная с адреса 2000, мы должны сделать определенные изменения в адресной части данной команды. С другой стороны, некоторые фрагменты программы (например, константа 3, сгенерированная в строке 85) должны остаться неизменными вне зависимости от начального адреса загрузки. Если рассматривать объектный код отдельно, то в общем случае невозможно определить какие значения представляют адреса, зависящие от месторасположения программы, а какие - неизменяемые объекты.

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

Для того чтобы детально обсудить возникающие здесь проблемы, рассмотрим программу на рис.2.5 и 2.6. В предыдущем разделе мы ассемблировали данную программу с нулевым начальным адресом. На рис. 2.7а показана ее загрузка с адреса 0. Команда JSUB (строка 15) загружается, начиная с адреса 0006. Ее адресное поле содержит значение 01036, которое является адресом команды с меткой RDREC. (Это, конечно, те же самые адреса, которые были назначены ассемблером.).

Предположим теперь, что мы хотим загрузить эту же программу с адреса 5000, как показано на рис. 2.7б. Теперь команда с меткой RDREC имеет адрес 6036. Таким образом, адресная часть команды JSUB должна быть модифицирована так, как показано на рисунке. Аналогично, если бы мы загрузили программу с адреса 7420 (рис. 2.7в), то потребовалось бы приведение команды JSUB к виду 4В108456, чтобы ее адресная часть соответствовала новому значению адреса RDREC.

Обратите внимание, что независимо от того, куда загружается программа, разница между адресом RDREC и началом программы составляет 1036 байт. Это означает, что мы можем

 

           
     


0000 ·

· ·

· ·

· ·

0006 4В101036 (+JSUB RDREC)

· ·

· ·

· ·

· ·

· ·

1036 В410 RDREC

· ·

· ·

· ·

· ·

· ·

1076 ·

5000 ·

· ·

· ·

· ·

5006 4В106036 (+JSUB RDREC)

· ·

· ·

· ·

· ·

· ·

6036 В410 RDREC

· ·

· ·

· ·

· ·

· ·

6076 ·

7420 ·

· ·

· ·

· ·

7426 4В108456 (+JSUB RDREC)

· ·

· ·

· ·

· ·

· ·

8456 В410 RDREC

· ·

· ·

· ·

· ·

· ·

8496 ·

           
   
 
     

 


а б в

 

Рис. 2.7. Примеры перемещения программ.

 

решить проблему перемещения программы следующим образом:

1. Когда ассемблер генерирует объектный код команды JSUB, мы полагаем, что он заносит адрес метки RDREC относительно начала программы. (Вот почему мы установили вначале счетчик адреса равным 0.).

2. Ассемблер, кроме того, вырабатывает команду для загрузчика, которая предписывает ему прибавить к содержимому адресного поля команды JSUB начальный адрес программы.

Естественно, что команда загрузчика должна быть составной частью объектной программы. Это можно сделать с помощью дополнительного типа записи объектного формата - записи-модификатора. Эта запись имеет следующий формат:

Запись-модификатор:

Столбец 1 М.

Столбцы 2-7 Начальный адрес модифицируемого адресного поля

относительно начала программы

(шестнадцатеричный).

Столбцы 8-9 Длина модифицируемого адресного поля в

полубайтах (шестнадцатеричная).

Длина хранится с полубайтах (а не в байтах), так как модифицируемое адресное поле не обязательно содержит целое число байтов. (Например, адресное поле в рассмотренной выше команде JSUB занимает 20 разрядов, что составляет 5 полубайтов.) Месторасположение модифицируемого адресного поля задается адресом байта, в котором содержатся старшие разряды адресного поля. Если модифицируемое адресное поле занимает нечетное количество полубайтов, то предполагается, что оно начинается с середины байта, адрес которого задан в столбцах 2-7.

Эти соглашения, естественно, тесно связаны с архитектурой УУМ/ДС. Для других типов машин представление длины адресного поля в полубайтах может оказаться неудобным (см. упр. 2.2.7).

Для команды JSUB, которую мы используем в качестве примера, запись-модификатор должна иметь вид

М00000705

Она указывает на то, что начальный адрес программы необходимо добавить к полю, которое начинается с адреса 00007 (относительно начала программы), и что длина адресного поля равна 5 полубайтам. Таким образом, в ассемблированной команде 4В101036 первые 12 разрядов (код 4В1) останутся неизменными. Адрес начала загрузки программы будет добавлен к последним 20 разрядам (01036) для того, чтобы получить правильный адрес операнда. (Вам следует самостоятельно убедиться в том, что это даст результат, показанный на рис. 2.7.).

Точно такие же действия необходимо выполнить для перемещения команд, заданных в строках 35 и 65 (распечатка 4). Остальные команды не требуют модификации при загрузке. В одних случаях потому, что операнды команд расположены не в оперативной памяти (например, CLEAR S или LDA #З). В других потому, что для задания операнда использована относительная адресация. Например, команда в строке 10 (STL RETADR) ассемблируется с помощью адресации относительно счетчика команд со смещением 02D. Неважно, с какого адреса будет фактически загружена программа. В любом случае слово, помеченное меткой RETADR, будет смещено на заданную величину (2D) относительно команды STL. Поэтому данную команду модифицировать не нужно, так как во время ее выполнения счетчик команд будет содержать реальный адрес следующей команды и, таким образом, процесс вычисления целевого адреса обеспечит получение правильного реального адреса, соответствующего RETADR.

Точно так же расстояние между LENGTH и BUFFER всегда будет равно трем байтам. Таким образом, после смещения команды в строке 160, использующей адресацию относительно базы, не будет требовать модификации при перемещении программы. (Содержимое базового регистра будет, конечно, зависеть от месторасположения программы однако его значение устанавливается автоматически при выполнении команды LDB #LENGTH, в которой используется адресация относительно счетчика команд.)

 

H_COPY _000000_001077 T_000000_1D_17202D_69202D_4B101036_032026_290000_332007_4B10105D_3F2FIC_032010 T_00001D_13_0F2016_010003_0F200D_4B10105D_3E2003_454F46 T_001036_1D_B410_B400_B440_75101000_E32019_332FFA_DB2013_A004_332008_57C003_B850 T_001053_1D_3B2FEA_134000_4F0000_F1_B410_774000_E32011_332FFA_53C003_DF2008_B850 T_001070_07_3B2FEF_4F0000_05

M_000007_05

M_000014_05

M_000027_05

E_000000

 

Рис. 2.8. Объектная программа, соответствующая рис.2.6.

 

Теперь нам абсолютно ясно, что модификация во время загрузки требуется только в командах, использующих прямую (как альтернатива относительной) адресацию. Для программ УУМ/ДС прямая адресация используется только в расширенном (4-байтовом) командном формате. Это существенное преимущество относительной адресации. Если бы мы попытались переместить программу, приведенную на рис.2.1, то увидели бы, что почти все команды требуют модификации.

На рис. 2.8 показано объектное представление, соответствующее исходной программе на рис.2.5. Обратите внимание, что записи тела программы остались такими же, как если бы они были подготовлены абсолютным ассемблером (с нулевым начальным адресом). Однако теперь адреса загрузки рассматриваются не как абсолютные, а как относительные величины. (То же самое, конечно, справедливо для адресов в записях-модификаторах и записи-конце.) Для каждого адресного поля, требующего настройки при перемещении программы, имеется своя запись-модификатор (в нашем случае их 3 и они все для команд +JSUB). Вам следует самостоятельно проверить каждую запись-модификатор и убедиться, что вы поняли, как она формируется. В гл. 3 мы детально рассмотрим, как загрузчик осуществляет требуемую модификацию программ. Сейчас важно, чтобы вы хорошо уяснили изложенные здесь концепции, так как они послужат основой для материала, обсуждаемого в следующем разделе.



Поделиться:


Последнее изменение этой страницы: 2017-02-17; просмотров: 169; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.116.51.117 (0.064 с.)