Что такое ассемблер?
Языки ассемблеров
Команды языка ассемблера
Код операции
Псевдооперации
Литералы
Свободный формат команд
Некоторые типичные команды ассемблера для машин с побайтовой организацией
Ассемблеры типа «трансляция — выполнение»
Однопроходный ассемблер
Двухпроходный ассемблер
Символы
Подробная блок-схема прохода
Подробная блок-схема прохода 2
Пример трансляции
Таблицы символов общие замечания
Обработка таблицы
Линейный поиск
Двоичный поиск
Сравнение двоичного и линейного способов поиска
Метод хеширования
Пример хеширования
Скученность
Назначение макрокоманды
Различие между макрокомандами и подпрограммами
Форматы макрокоманды
Ключевой макрос
Макропроцессор

Подробная блок-схема прохода 2

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

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

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

Счетчик размещения переустанавливается в нуль, и операторы исходного языка снова читаются один за другим.
Поля метки распечатываются, если требуется распечатка данного исходного оператора, и игнорируются в противном случае, так как они уже полностью обработаны на проходе 1. Как и на проходе 1, содержимое поля операции сравнивается с ключами таблицы псевдоопераций. Если они равны, то команда является псевдооперацией и обрабатывается, соответствующей подпрограммой, адрес которой выбирается из таблицы псевдоопераций. Для псевдоопераций USING и DROP регистры, упомянутые в поле операнда, помечаются соответственно как доступные или как недоступные в таблице, обеспечивающей прослеживание доступных базовых регистров и их фактического содержимого. Отводящие память псевдооперации DS были обработаны на проходе 1, а для псевдоопераций DC нужно сгенерировать фактический код в требуемом представлении и занести его на место, определенное на проходе 1.

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

Это вычисление зависит от формата команд. Различные типы команд требуют несколько отличной обработки.
Если какой-либо из операндов расположен в регистре, заданном либо прямо посредством его номера, либо косвенно посредством символического имени, номер регистра помещается в соответствующую часть машинной команды. Если операнд расположен в памяти, для адресации которой необходим базовый (а также, возможно, и индексный) регистр (типы команд RX, RS, SS, SI), содержимое индексного регистра с (X) (если он необходим) вычитается из адреса памяти Л, сгенерированного на проходе 1. Затем исследуется таблица доступных базовых регистров для того, чтобы найти в ней подходящий базовый регистр, такой, что 0<D=A—с(Х)—с(В)<С <4096, где с (В) — содержимое некоторого доступного базового регистра. Если таких регистров несколько, выбирается тот из них которому соответствует минимальное значение смещения D. Определенные таким образом номер базового регистра и значение смещения помещаются в поле базового регистра и поле смещения команды. Если длина операнда может меняться, ее значение, вычисленное на проходе 1, также используется при сборке машинной команды. Затем собранная команда, выдается для дальнейшей обработки редактором связей и (или) загрузчиком. Обычно она записывается на диск, а в некоторых старых системах перфорируется на перфокартах. Значение счетчика размещения увеличивается, и можно начинать обработку следующего оператора. На практике несколько операторов исходного языка объединяются в одну запись на диске или на одной карте, но это не влияет на описанный здесь метод.

Как и на проходе 1, псевдооперация END сигнализирует о конце исходной программы и завершает проход 2. Для завершения трансляции выполняются различные «хозяйственные» задачи, такие, как генерация кодов для литералов из таблицы литералов и выдача таблицы глобальных символов.

Hosted by uCoz