Вход в систему

Лекции по курсу "Проектирование ассемблеров, компоновщиков, макропроцессоров

15. Пример работы многопросмотрового ассемблера

 

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

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


ALPHA EQU BETA

BETA EQU DELTA

DELTA EQU 1

Когда во время первого просмотра встретится метка BETA, мы не сможем назначить ей адрес, так как DELTA еще не определена. Поэтому мы не сможем вычислить значение метки ALPHA во время второго просмотра. Это означает, что любой ассемблер, выполняющий только два последовательных просмотра исходной программы, не может обрабатывать такие последовательности определений.

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

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

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

1 HALFSZ EQU MAXLEN / 2
2 MAXLEN EQU BUFEND-BUFFER
3 PREVBT EQU BUFFER-1
  *
  *
4 BUFFER db 4096 dup(?)
5 BUFEND EQU $

 

На рис. a) приведены элементы таблицы имен, получившиеся после первого просмотра предложения HALFSZ EQU MAXLEN/2.

Имя MAXLEN еще не определено, поэтому невозможно вычислить значение HALFSZ. Вместо значения HALFSZ в таблице имен запоминается определяющее его выражение. Элемент &1 показывает, что в определяющем выражении не определено одно имя. Конечно, в реальной реализации это определение может храниться где-нибудь в другом месте. Таблица имен может просто содержать указатель на определяющее выражение. Имя MAXLEN также занесено в таблицу имен и снабжено признаком *, указывающим на то, что оно не определено. С этим именем связан список имен, значения которых зависят от MAXLEN; в данном случае HALFSZ. Обратите внимание на схожесть со способом обработки ссылок вперед в однопросмотровом ассемблере.

Аналогично обрабатывается определение MAXLEN (рис. b). В данном случае в состав определения входят два неопределенных имени: BUFEND и BUFFER. Оба этих имени заносятся в таблицу имен вместе со списком, указывающим на зависимость MAXLEN от этих имен. Точно так же при обработке определения PREVBT потребуется занесение этого имени в список имен, зависящих от BUFFER (рис. с).

До сих пор мы просто запоминали определения имен для последующей обработки. Определение BUFFER в строке 4 позволяет начать вычисление некоторых из них. Предположим, что, когда мы читаем строку 4, счетчик размещений содержит шестнадцатеричное значение 1034. Этот адрес запоминается в качестве значения BUFFER. Затем ассемблер просматривает список имен, зависящих от значения BUFFER. Элемент таблицы имен для первого имени данного списка (MAXLEN) показывает, что он зависит от двух имен, которые к данному моменту не определены. Поэтому сразу вычислить значение MAXLEN нельзя. Вместо этого &2 заменяется &1 для того, чтобы показать, что теперь только одно имя в определении (BUFEND) осталось неопределенным. Другое имя списка (PREVBT) можно вычислить, так как оно зависит только от BUFFER. Выражение, определяющее значение PREVBT, вычисляется и запоминается в таблице имен. Результат показан на рис. d).

Дальнейшая обработка осуществляется аналогично. Когда в строке 5 определяется BUFEND, его значение заносится в таблицу имен. Список, связанный с BUFEND, предписывает ассемблеру вычислить MAXLEN, а занесение значения MAXLEN вызывает, в свою очередь, вычисление имен из связанного с ним списка (HALFSZ). Как показано на рис. e), на этом процесс определения имен заканчивается. Если какие-либо имена остаются неопределенными, то они отмечаются как ошибочные.

Процедура, которая только что была описана, применяется к именам, определяемым с помощью директив ассемблера типа EQU.

 

Введение
Причины использования языка ассемблер
Причины неиспользования языка ассемблер
Синтаксис ассемблера
Системное программное обеспечение и структура ЭВМ
Программная модель процессора Intel 8086
Организация работы памяти
Операнды
Адресация операндов
Формат машинных команд
Команды переходов
Типы ассемблеров. Функции ассемблера
Ассемблер по схеме 1А / ОП
Ассемблер по схеме 1А / МД
Двухпросмотровый ассемблер
Многопросмотровый ассемблер
Загрузчик
Структура объектных файлов. Основные понятия
Идентификация модуля и атрибуты
Концепция привязки
Объектный файл. Последовательность записей
Объектный файл. Формат записей
Формат записей THEADR и LHEADR
Формат записи LNAMES
Формат записи SEGDEF
Формат записи GRPDEF
Формат записи PUBDEF
Формат записи COMDEF
Формат записи LOCSYM
Формат записи EXTDEF
Формат записи LINNUM
Формат записи LEDATA
Формат записи LIDATA
Формат записи FIXUPP
Формат записи MODEND
Формат записи комментариев


исполнялось 0,106635 c, запросов к базе 6