Выдача ассебмлера

Вы уже должны научиться самостоятельно писать и отлаживать программы, используя рассмотренные приемы и методы. В предыдущем разделе был рассмотрен процесс трансляции команд формата RR. Теперь вам будет не только интересно, но и полезно изучить функции ассемблера более подробно.

ЛИСТИНГ АССЕМБЛЕРА

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

На рис. 6.2 представлена распечатка, выдаваемая ассемблером при обработке программы, приведенной на рис. 5.10. Листинг состоит из шести частей (колонок), имеющих названия LOC, OBJECT CODE, ADDR1, ADDR2, STMT и SOURCE STATEMENT соответственно. Колонка SOURCE STATEMENTсодержит исходную программу на языке ассемблера именно в том виде, в котором она набита на перфокартах.

Каждому предложению исходной программы присваивается определенный номер. Эти номера напечатаны в колонке STMT. Отметим, что предложения нумеруются не последовательными числами натурального ряда. Посмотрите хотя бы на разницу между номером предложения INITIAL и номером следующего предложения. Дело в том, что INITIAL, RWD, WWD, EOJ являются макрокомандами, эквивалентными нескольким командам языка ассемблера. Поскольку мы использовали предложение PRINT NOGEN, то состав этих макро не распечатывается. Но тем не менее соответствующие предложения включены в программу и им присвоены номера так же, как и всем остальным предложениям. Номера предложений печатаются для удобства. Позже мы увидим, что указания об ошибках выдаются вместе с номерами предложений, в которых они встречаются. Номера используются исключительно для ссылок на соответствующие им предложения в программе.

Статья 376 - Картинка 1

Рис. 6.2. Листинг ассемблера.

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

В программе на рис. 6.2 под номером 25 значится предложение SR 9,6 DECREMENT LOOP COUNTER

Значение счетчика размещения, соответствующее этому предложению, равно 00007Е, указывая, что начало машинного эквивалента команды SR отстоит от начала программы на 7Е16 байтов. Поскольку эта команда является командой формата RR, то, значит, ее длина равна 2 байтам. Поэтому следующая команда ВР отстоит от начала еще на 2 байта, и соответствующее ей значение счетчика равно 000080. Команда ВР имеет длину 4 байта, поэтому, естественно, значение счетчика для следующей команды — 000084.

Результатом включения в программу предложения PRINT NOGEN является, кроме всего прочего, подавление выдачи содержимого счетчика размещения для всех команд, замещающих макрокоманды. Например, 20-я команда (RWD) вызывает скачок значения счетчика размещения на CiB. Это означает, что машинный эквивалент макро RWD имеет длину 12 байтов. Отметим, что команды ассемблера, например END, не влияют на счетчик, поскольку не транслируются в машинные команды.

Колонка OBJECT CODE содержит уже отранслированную программу на машинном языке. Например, в колонке OBJECT CODE в строке, соответствующей 25-му предложению, мы находим 1В96, шестнадцатеричный машинный эквивалент команды

SR 9,6

Аналогично можно определить, что командой машинного языка, соответствующей предложению 26:

ВР NEXTNUM является 4720D05A.

Как вы помните, в соответствии с типом команды один или два операнда могут находиться в памяти. Относительные адреса этих операндов, определяемые с помощью счетчика размещения, можно найти в колонках ADDR1 и ADDR2. Например, для предложения 26 в колонке ADDR2 указан номер 00072. Поскольку предложение с именем NEXTNUM является макрокомандой, то относительный адрес NEXTNUM не указывается. Однако, так как предыдущее предложение имеет адрес 00070 и длину два байта, то, естественно, значение счетчика размещения, соответствующее имени NEXTNUM, равно 00072. Впоследствии мы увидим, что значения счетчика размещения, указываемые в колонках ADDR, на самом деле не являются реально используемыми в программе адресами. Однако они используются при вычислении этих адресов.

Ассемблер

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

В большинстве систем-фирмы IBM для трансляции используется ассемблер F. Этот ассемблер является двухпроходным макроассемблером. Процесс ассемблирования состоит из двух этапов, этапа макрогенерации и этапа трансляции, осуществляемого в два прохода.

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

На первом проходе ассемблирования получается скелет результирующей программы на машинном языке. Каждому предложению сопоставляется адрес, равный соответствующему значению счетчика размещения, и строится таблица имен. Любое символическое имя, встречающееся в исходной программе, описывается в этой таблице только один раз. Для каждого такого символического имени указывается значение счетчика размещения, соответствующее положению, в котором данное имя было определено, и длина в байтах идентифицируемого этим именем объекта. Например, элемент таблицы для имени NEXTNUM программы, приведенной на рис. 6.2, выглядит так:

Имя

Длина

Адрес

NEXTNUM

00004

000072

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

Статья 376 - Картинка 2

Рис. 6.3. Листинг ассемблера программы с синтаксическими ошибками.

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

Сообщения об ошибках

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

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

Из распечатки видно, что допущены три ошибки. Ошибки в распечатке отмечаются строками

*** ERROR ***

после каждого неправильного предложения. На странице DIAGNOSTICS (диагностика) указывается сущность совершенных ошибок. В колонке STMT указываются номера предложений с ошибками. MESSAGE — краткое описание допущенных ошибок. Так, например, мы видим, что предложение 26 содержит в поле операндов неопределенное имя.

Возвращаясь к распечатке ассемблера, легко заметить, что вместо NEXTNUM случайно набито NEXTNMU. Предложение 27 содержит недействительный код операции. Здесь BN должно быть заменено на ВМ.

В колонке ERROR CODE содержатся идентификаторы ошибок. Эти идентификаторы могут быть использованы для поиска более детального описания соответствующих ошибок в руководствах.

Статья 376 - Картинка 3

Рис. 6.4. Диагностические сообщения для программы рис. 6.3.