Двухпросмотровый ассемблер с оверлейной структурой 


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



ЗНАЕТЕ ЛИ ВЫ?

Двухпросмотровый ассемблер с оверлейной структурой



Как мы видели, в большинстве ассемблеров процесс обработки исходной программы делится на два просмотра. Внутренние таблицы и подпрограммы, которые используются только во время первого просмотра, становятся ненужными после его завершения. Многие подпрограммы и таблицы используются только для одного просмотра и никогда не требуются для другого. В то же время некоторые таблицы (например, SYMTAB) и подпрограммы (например, поиск в SYMTAB) используются в обоих просмотрах.

На рис. 2.18 представлена общая структура двухпросмотрового ассемблера. Этот ассемблер состоит из трех сегментов, образующих дерево. Корневой сегмент содержит простую управляющую программу, функцией которой является поочередный вызов двух других сегментов (Просмотр 1 и Просмотр 2). Корневой сегмент содержит таблицы и подпрограммы, необходимые для обоих просмотров.

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

 
 


Управляющая

программа

Общие

Корневой таблицы

сегмент и под-

программы

       
   
 
 

 

 


Подпрограммы Подпрограммы

Сегмент и таблицы и таблицы Сегмент

Просмотр 1 первого второго Просмотр 2

просмотра просмотра

       
   


Рис. 2.18. Структура двухпросмотрового ассемблера.

 

Просмотр 1, и ассемблер выполняет первый просмотр. После его завершения на место сегмента Просмотр 1 загружается

 

 

Максимальная Объем

память, тре- памяти

буемая при занимаемый

оверлейной всеми под

загрузке программами

и таблицами

ассемблера

               
   
       
 


Управляющая Управляющая

программа программа

Резидентная

Общие часть Общие

таблицы таблицы

и подпрог- и подпрог-

раммы раммы

       
   


Подпрог- Подпрог-

раммы раммы

первого Загружаются второго

просмотра на одно и то просмотра

же место

Таблицы в оперативной Таблицы

первого памяти второго

просмотра просмотра

       
   

 

 


Рис. 2.19. Двухпросмотровый ассемблер с оверлейной структурой.

 

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

Программа, построенная подобным образом, называется оверлейной программой или программой с перекрытием, так как во время ее исполнения некоторые из ее сегментов перекрывают другие. В гл. 3 мы более подробно обсудим оверлейные программы и рассмотрим, как они обрабатываются загрузчиком и сервисными процедурами операционной системы.

Однопросмотровые ассемблеры

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

Довольно легко исключить ссылки вперед на данные; достаточно потребовать, чтобы все области данных определялись в исходной программе раньше, чем появляются команды, которые на них ссылаются. Это не слишком жесткое ограничение. Программист просто размещает все области данных в начало программы, а не в конце. К несчастью, невозможно столь же легко исключить ссылки вперед на метки команд. Логика программы часто требует передачи управления вперед. (Например, выход из цикла после проверки некоторого условия.) Требование исключить все такие передачи управления оказалось бы гораздо более жестким и неудобным. Поэтому ассемблер должен предпринимать специальные меры для обработки ссылок вперед. Однако для того, чтобы облегчить задачу, многие однопросмотровые ассемблеры действительно запрещают (или по крайней мере не рекомендуют) ссылки вперед на данные.

Существует два основных типа одиопросмотровых ассемблеров. Ассемблеры первого типа записывают объектный код не посредственно в оперативную память для немедленного исполнения; ассемблеры второго тина создают объектную программу, которая будет выполняться позднее. Обсуждение обоих типов мы проиллюстрируем с помощью программы на рис.2.20. Это тот же самый пример, что и на рис.2.2, по все определения данных расположены перед командами, в которых они используются. Сгенерированный объектный код показан на рис.2.20 только для справки.

 

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

0 1000 COPY START 1000

1 1000 EOF BYTE C"EOF" 454F46

2 1003 THREE WORD 3 000003

3 1006 ZERO WORD 0 000000

4 1009 RETARD RESW 1

5 100C LENGTH RESW 1

6 100F BUFFER RESB 4096

9 *

10 200F FIRST STL RETADR 141009

15 2012 CLOOP JSUB RDREC 48203D

20 2015 LDA LENGTH 00100C

25 2018 COMP ZERO 281006

30 201B JEQ ENDFIL 302024

35 201E JSUB WRREC 482062

40 2021 J CLOOP 3С2012

45 2024 ENDFIL LDA EOF 001000

50 2027 STA BUFFER 0С100F

55 202A LDA THREE 001003

60 202D STA LENGTH 0С100C

65 2030 JSUB WRREC 482062

70 2033 LDL RETADR 081009

75 2036 RSUB 4С0000

110 *

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

120 *

121 2039 INPUT BUTE X"F1" F1

122 203A MAXLEN WORD 4096 001000

124 *

125 203D RDREC LDX ZERO 041006

130 2040 LDA ZERO 001006

135 2043 RLOOP TD INPUT E02039

140 2046 JEQ RLOOP 302043

145 2049 RD INPUT D82039

150 204C COMP ZERO 281006

155 204F JEQ EXIT 30205B

160 2052 STCH BUFFER,X 54900F

165 2055 TIX MAXLEN 2C203A

170 2058 JLT RLOOP 382043

175 205B EXIT STX LENGTH 10100C

180 205E RSUB 4C0000

195 *

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

205 *

206 2061 OUTPUT BYTE X"05" 05

210 2062 WRREC LDX ZERO 041006

215 2065 WLOOP TD OUTPUT E02061

220 2068 JEQ WLOOP 302065

225 206B LDCH BUFFER,X 50900F

230 206E WD OUTPUT DC2061

235 2071 TIX LENGTH 2C100C

240 2074 JLT WLOOP 382065

245 2077 RSUB 4C0000

255 END FIRST

 

Рис.2.20. Модельная программа для однопросмотрового ассемблера.

 

Мы обсудим, как однопросмотровый ассемблер каждого типа мог бы в действительности сгенерировать требуемую объектную программу.

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

Поскольку генерируемая объектная программа вместо того, чтобы записываться на внешнюю память, располагается в оперативной памяти, то обработка ссылок вперед оказывается менее сложной. Ассемблер просто генерирует команды объектного кода по мере просмотра исходной программы. Если операндом команды является еще неопределенное имя, то при ассемблировании команды обработка ее адресной части пропускается. Имя, использованное в качестве операнда, заносится в таблицу имен (если оно не было занесено ранее). Строка таблицы помечается признаком, указывающим на то, что данное имя еще не определено. Адрес операндного поля команды, ссылающейся на неопределенное имя, добавляется в список ссылок вперед, связанный с соответствующим элементом таблицы имен. Если встречается определение имени, то просматривается его список ссылок вперед (если он есть) и требуемый адрес заносится в каждую предварительно сгенерированную команду.

Рассмотрим пример, который поможет прояснить этот процесс. На рис. 2.21а показано, как будут выглядеть объектный код и элементы таблицы имен после просмотра строки 40 программы на рис.2.20. Первая ссылка вперед была в строке 15. Поскольку операнд (RDREC) еще не был определен, то команда ассемблировалась без назначения адреса для этого операнда (на рисунке обозначено как ----). Затем имя RDREC было занесено в SYMTAB как неопределенное имя (обозначено *), а адрес операндного поля команды (2013) был занесен в список, связанный с RDREC. Аналогично обрабатывались команды в строках 30 и 35.

 

Адрес

памяти Содержимое Имя Значение

           
     
 


1000 454F4600 00030000 00xxxxxx xxxxxxxx LENGTH 100C

1010 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

RDREC * 2013 0

       
   


THREE 1003

 
 


2000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx14 ZERO 1006

2010 100948-- --00100C 28100630 -------48--

2020 --3C2012 WRREC * 201F 0

       
   


EOF 1000

       
   


ENDFIL * 201C 0

       
   


RETARD 1009

 
 


BUFFER 100F

 
 


CLOOP 2012

 
 


FIRST 200F

 
 

 


a

 

 

Адрес

памяти Содержимое Имя Значение

           
     
 


1000 454F4600 00030000 00xxxxxx xxxxxxxx LENGTH 100C

1010 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

RDREC 203D

 
 


THREE 1003

 
 


2000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx14 ZERO 1006

2010 10094820 3D00100C 28100630 202448--

2020 --3C2012 0010000C 100F0010 030C100C WRREC * 201F 2031 0

2030 48-----08 10094C00 00F10010 00041006

2040 001006E0 20393020 43D82039 28100630 EOF 1000

2050 ------5490 0F

ENDFIL 2024

 
 


RETARD 1009

 
 


BUFFER 100F

 
 


CLOOP 2012

 
 


FIRST 200F

 
 


MAXLEN 203A

 
 


INPUT 2039

       
   


EXIT * 2050 0

       
   


RLOOP 2043

 
 

 

 


б

 

Рис. 2.21. Объектные коды, записанные в оперативную память, и элементы таблицы имен после просмотра строки 40 (а) и строки 160 (б) программы на рис.2.20.

 

Рассмотрим теперь рис. 2.21б, соответствующий ситуации после просмотра строки 160. К этому моменту была разрешена часть ссылок вперед, в то время как другие были добавлены. Когда было определено имя ENDFIL (строка 45), ассемблер занес его значение в SYMTAB. Затем он занес это значение в операндное поле команды (по адресу 201С), как это предписано списком ссылок вперед. С этого момента все ссылки на ENDFIL не будут являться ссылками вперед и не будут заноситься в список. Аналогично определение RDREC (строка 125) позволило заполнить операндное поле по адресу 2013. Тем временем были добавлены две новые ссылки вперед: WRREC (строка 65) и EXIT (строка 155). Вам следует продолжить этот процесс до конца программы и самостоятельно убедиться в том, что все ссылки вперед будут занесены правильно. Когда будет обнаружен конец программы, все элементы SYMTAB с признаком * будут указывать на неопределенные имена, и, следовательно, ассемблер должен отметить их как ошибки.

По достижению конца программы ассемблирование завершается. Если не было ошибок, то ассемблер ищет в SYMTAB значение имени, указанное в предложении END (в данном случае FIRST), и передает управление на данный адрес для исполнения ассемблированной программы.

В нашем примере мы использовали абсолютную программу, так как для ассемблера типа загрузка-выполнение фактический адрес загрузки должен быть известен во время ассемблирования. Конечно, необязательно, чтобы адрес загрузки определялся программистом; он может назначаться и системой. Это не влияет на процесс ассемблирования, так как в любом случае в счетчик размещений будет занесен фактический адрес начала программы.

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

Иллюстрация этого процесса дана на рис. 2.22. Вторая запись тела программы содержит код, сгенерированный для строк 10 - 40 исходной программы, изображенной на рис. (см. распечатку). Адреса операндов команд для строк 15, 30 и 35 сгенерированы с нулевым значением. Когда в строке 45 встречается определение имени ENDFIL, ассемблер генерирует третью запись тела программы. Эта запись определяет, что значение 2024

 

H_COPY _001000_00107A

T_001000_09_454F46_000003_000000 T_00200F_15_141009_480000_00100C_281006_300000_480000_3C2012

T_00201C_02_2024

T_002024_19_001000_0C100F_001003_0C100C_480000_081009_4C0000_F1_001000

T_002013_02_203D T_00203D_1E_041006_001006_E02039_302043_D82039_281006_300000_54900F_2C203A_382043 T_002050_02_205B

T_00205B_07_10100C_4C0000_05

T_00201F_02_2062

T_002031_02_2062

T_002062_18_041006_E02061_302065_50900F_DC2061_2C100C_382065_4C0000

E_00200F

 

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

 

(адрес ENDFIL) должно быть занесено по адресу 201С (адресное поле операнда команды JEQ в строке 30). Таким образом, во время загрузки программы величина 2024 заменит ранее занесенное значение 0000. Точно так же обрабатываются и другие ссылки вперед нашей программы. В результате для разрешения ссылок вперед, которые не могут быть обработаны ассемблером, используются средства загрузчика. Конечно, при передаче объектной программы загрузчику должен быть сохранен первоначальный порядок ее записей.

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



Поделиться:


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

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