Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Двухпросмотровый ассемблер с оверлейной структурой
Как мы видели, в большинстве ассемблеров процесс обработки исходной программы делится на два просмотра. Внутренние таблицы и подпрограммы, которые используются только во время первого просмотра, становятся ненужными после его завершения. Многие подпрограммы и таблицы используются только для одного просмотра и никогда не требуются для другого. В то же время некоторые таблицы (например, 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 с.) |