Условное ассемблирование

Под условным ассемблированием понимается возможность изменять порядок работы ассемблера в зависимости от выполнения или невыполнения некоторых условий в процессе ассемблирования программы. Мы знаем, что ассемблер различает два типа символических переменных: символические параметры, значения которым присваиваются с помощью предложения-прототипа или самой макрокоманды, и SET-переменные, для присваивания значений которым используются предложения SETx. Мы также знаем, что ассемблер может определять значения различных атрибутов, зависящие от значений символических параметров. Фактически мы можем рассматривать ассемблер как обычную программу. В качестве данных выступает исходная программа, присвоение значений переменным которой выполняется с помощью механизма символических параметров. Возможность «вычисления» различных значений обеспечивается механизмом конкатенации и SET-предложений. Однако пока еще мы не имеем в распоряжении средств, позволяющих осуществлять управление работой ассемблера в зависимости от начальных данных и результатов предыдущих вычислений.

Существуют две команды перехода ассемблера: команда безусловного перехода, AGO (Assembler GO), и условного перехода, AIF (Assembler IF). Необходимо различать команды перехода ассемблера и машинные команды передачи управления, ВС и BCR. Последние вызывают изменение содержимого счетчика команд в процессе выполнения некоторой программы и, таким образом, изменение порядка выполнения процессором команд этой программы. Наличие таких команд позволяет пропускать некоторые команды программы или организовывать циклическую работу. С другой стороны, команды перехода ассемблера вызывают изменение порядка обработки ассемблером символических предложений и исходной программы. Таким образом, некоторые команды исходной программы могут быть нескомпилированы вообще, а некоторые — скомпилированы по многу раз.

Разница между командами перехода ассемблера и аналогичными машинными командами станет совсем очевидной, если заметить, что переходы ассемблера осуществляются на предложения с определенными метками следования, а не с именами, как было в случае машинных переходов. Первым символом метки следования должна быть точка (.). За точкой может следовать последовательность из не более чем семи элементарных символов, первый из которых должен быть буквой. Допустимыми метками следования являются, например, .N, .N135 и .ABDDQ. Метки следования используются ассемблером для определения места, на которое следует совершить переход по команде перехода, т. е. для определения предложения, которое нужно обрабатывать следующим. В отличие от обычных меток, являющихся не чем иным как символическими именами адресов памяти, метки следования соответствующих им физических объектов не имеют. На самом деле все метки следования удаляются ассемблером из программы еще до начала ее трансляции на машинный язык.

Команда AGO имеет вид

пробел или метка следования AGO метка следования

Результатом выполнения команды AGO является переход ассемблера к обработке предложения, имеющего метку следования, указанную в поле операндов. Например, еслимыимеем

то ассемблер обработает команду загрузки, а затем команду ST пропустит. Если &САТ имеет значение СТ(5), a &MOUSE — МТ, то после выполнения начальной обработки указанного фрагмента программы получим

L 3,СТ(5)

А 3,МТ

Заметим, что ассемблер удалил метку следования команды сложения. Команда условного перехода ассемблера AIF имеет вид

пробел или метка следования AIF (логическое выражение)

метка следования

Так же как и все предложения условного ассемблирования, предложение AIF может быть помечено меткой следования.

Логическое выражение может иметь одно из двух значений: истина или ложь (Гили 0). Если выражение имеет значение истина (1), то в качестве следующего обрабатываемого предложения ассемблером выбирается предложение с меткой следования, указанной в поле операндов команды AIF. Если выражение имеет значение ложь (0), ассемблер переходит к обработке предложения, следующего за предложением AIF. Логическое выражение в простейшем виде выглядит как

операнд1 отношение операнд2

В данном случае в качестве операндов выступают символические переменные, атрибуты или константы. Отношение может быть одним из следующих:

EQ: равно

NE: не равно

GT: больше

LT: меньше

GE: больше или равно

LE: меньше или равно

(Знакомые с языком ФОРТРАН сразу узнают здесь операторы отношений IF-предложений.Однако заметим, что в данном случае никаких дополнительных точек не пишется.) Логическое выражение истинно, если отношение

операнд1 отношение операнд2

выполняется. Таким образом, выражение

6 GT 4

истинно, а

Т'&ОР ' EQ 'О'

ложно, если параметру &ОР макрокоманды было присвоено некоторое значение.

В качестве примера AIF-предложения рассмотрим предложение .GO AIF (&CHAR EQ 'PUNT').QUIT

В данном случае предполагается, что &CHAR — либо SETC-переменная, либо символический параметр. В последнем случае в сравнении участвует строка символов, присвоенная в качестве значения параметру &CHAR. Если исследуемые строки оказались одинаковыми, то ассемблер переходит к обработке предложения с меткой следования .QUIT. Если результат сравнения отрицательный, т. е. строки разные, то обработка программы продолжается так, как будто бы AIF- предложения не было.

AIF-предложение используется для условного управления ассемблером. Одним из часто встречающихся случаев является проверка типа операндов для выяснения типа необходимой машинной команды. В определении макро RWD (рис. 18.1 и 18.2) считалось, что в качестве операндов могут выступать только номера регистров.

Если же мы хотим иметь возможность задавать в качестве фактического параметра RWD как номер регистра, так и адрес ячейки памяти, то мы должны организовать проверку типа заданных параметров в макрокоманде и внесение в зависимости от результата проверки в программу команды LR (регистры) или команды ST (ячейки памяти). Макроопределение, изображенное на рис. 18.7, иллюстрирует сказанное.

При выполнении AIF-предложения происходит проверка атрибута типа параметра &LOC. Если &LOC не является самоопределенной величиной (т. е. номером регистра), мы считаем, что это адрес некоторой ячейки памяти, и заставляем ассемблер включать в макрорасширение предложения, начиная c.SYMADD. Если &LOC—номер регистра, то в макрорасширение включается предложение LTR, следующее сразу за AIF.

Рис. 18.7. Макро RWD, использующее условное ассемблирование для работы с операндами как в регистрах, так и в памяти.

Затем выполнение AGO приводит к пропуску оставшихся предложений и переходу к предложению MEND.

Если в качестве RWD принять определение, приведенное на рис. 18.7, то макрорасширением для макрокоманды

BNECH RWD

будет

BNECH L ABL(6) 15, — V($$IO)

BALR 14,15

LTR 1,1

ST 1, ABL(6)

а для

HCENB RWD 7

расширением будет

HCENB L 15, = V($$IO)

BALR 14,15

LTR 7,1

 

Существуют также некоторые другие средства языка, позволяющие более просто и гибко организовывать условное ассемблирование. Одним из таких средств является оператор ANOP (Assembler NO OPeration), предназначенный исключительно для удобства расположения меток следования. Никакой фактической операции по команде ANOP не выполняется. Достаточно часто встречаются ситуации, когда желательно пометить меткой следования машинную команду, уже имеющую метку. На рис. 18.8 приведено модифицированное определение уже встречавшегося макро COMPARE. Теперь с его помощью можно производить сравнение как чисел, так и строк символов. Если сравниваются строки, то для обеспечения возможности выполнения команды CLC необходимо-определить их длину. Таким образом, если параметр &TYPE имеет значение LC, то длина определяется с помощью ключевого параметра &LEN. Вся проблема состоит в том, что с помощью AIF-предложения можно организовать переходы лишь на предложения, помеченные меткой следования.

Рис. 18.8. Пример применения ANOP.

Нам бы хотелось поместить метку следования в поле метки команды CLC, но там уже стоит метка &LABEL. Таким образом, сначала ассемблер осуществляет переход на предложение ANOP, помеченное меткой следования .CHARS, а затем переходит к обработке предложения CLC.

В качестве примера рассмотрим макрокоманду

HERE COMPARE 5,BAT,EQULS,NEQULS,TYPE = Н

Ее макрорасширение выглядит так:

HERE СН 5,ВАТ

BE EQULS

В NEQULS

Макрорасширением же макрокоманды

THERE COMPARE WDS, MWDS,E,N,TYPE=LC,

LEN = 55

является

THERE CLC WDS(55),MWDS

BE E

В N

Все написанные нами до сих пор макроопределения не очень хороши, так как ни в одном из них не предусмотрена проверка на наличие возможных ошибок. Например, при выполнении RWD должна производиться проверка на присутствие операнда, а если операндом является регистр, то нужно также проверить, не является ли этот регистр одним из «специальных» регистров, какими являются регистрыО, 1, 13, 14 и 15.

Сначала отметим, что логические выражения, рассматривавшиеся выше, могут также строиться с участием связок AND и OR. Например, логическое выражение в поле операндов предложения

AIF (T'&LEN EQ 'O' AND '&TYPE' EQ 'LC').GHRN

принимает значение «истина», если в одно и то же время значение параметра &LEN не задано, а значением параметра &TYPE является строка LC.

 

Рис. 18.9. Определение RWD с контролем корректности операндов.

Если это так, то происходит переход на предложение с меткой следования GHRN. С помощью предложения MNOTE (Macro NOTE) можно запрашивать распечатку различных сообщений в выдаче ассемблера. Включив в программу предложение

MNOTE код серьезности,'сообщение'

мы получим в выдаче ассемблера на том месте, где данное предложение должно входить в макрорасширение, распечатку соответствующей строки. Кодом серьезности является число, характеризующее степень серьезности ошибки, повлекшей распечатку сообщения по команде MNOTE. Самой низкой степенью серьезности является 0, при этом процесс обработки программы продолжается в обычном порядке. Максимальной степенью серьезности является 255. По окончании процесса ассемблирования число, характеризующее степень серьезности, передается системе. Операционная система производит проверку величины этого числа для определения возможности перехода к выполнению следующего шага. Степень серьезности 0 означает отсутствие существенных ошибок; 4 свидетельствует о том, что отмеченные ошибки, по всей вероятности, не повлияют на результаты работы; 8 и более вызывает прекращение выполнения задания. Таким образом, в макрорасширении печатается строка

MNOTE 12',***ERROR***MISSING OPERAND'

Код 12 говорит о том, что продолжение выполнения обработки программы является бессмысленной тратой времени. С помощью MNOTEнадо стараться выдавать четкие и бросающиеся в глаза сообщения.

Рис. 18.10. Другое определение макро BEGIN, обеспечивающее область сохранения если пользователь ее не задал.

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

На рис. 18.9 приведен еще один вариант макроопределения RWD. Теперь уже в нем предусмотрены проверки на отсутствие операнда и на недопустимый номер регистра. Отметим использование SETA-пepeменной &REG для выполнения арифметических сравнений в предложениях условного ассемблирования. Кроме того, в данном случае мы впервые ввели в употребление предложение MEXIT (Macro EXIT). С его помощью мы требуем от ассемблера прекращения обработки рассматриваемого в настоящий момент макроопределения. MEXIT отличается от MEND тем, что оно может встречаться в произвольном месте макроопределения, в то время как MEND всегда последнее предложение макроопределения, свидетельствующее о его окончании.

На рис. 18.10 приведено новое определение макро BEGIN. Теперь, если пользователь сам не сообщит адрес области сохранения, это будет сделано за него.

В качестве последнего примера условного ассемблирования мы рассмотрим организацию циклической работы ассемблера для составления таблицы степеней числа 2.Таблица состоит из последовательности полных слов, количество которых определяется операндом макрокоманды. Первое слово расширения будет содержать 2, второе 4, третье 8 и т.д. В макроопределении TWOTAB, приведенном на рис. 18.11, использованы SETA-переменные &CTR H&POWER в качестве счетчика цикла и текущей степени 2 соответственно. Кроме того, для того чтобы избежать многократного определения метки, использована SETC-переменная &DLAB. При первом прохождении цикла, значением &DLAB является значение параметра-метки &LAB. Затем &DLAB принимает значение пустой строки. Таким образом, значение &LAB появляется в качестве метки в макрорасширении всего один раз. Расширением макрокоманды

является

TWOS DS F'2'

DS F'4'

DS F'8'

DS F'16'

Рис. 18.11. Макро для создания таблицы степеней числа 2.

Определенные трудности возникают, если мы хотим пометить модельное предложение. Пусть, например, макрокоманда использует регистр 5 для хранения промежуточных результатов, но исходное содержимое его мы хотим сохранить. Схема соответствующего определения может выглядеть, например, так:

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

Для решения возникшей проблемы используется системная переменная &SYSNDX. Переменная &SYSNDX, так же как и SETA-переменные, может иметь лишь числовые значения. Сначала ее значение равно 0001, а затем оно увеличивается на 1 всякий раз, когда макрокоманда встречается в программе. При конкатенации с некоторым именем &SYSNDX прибавляет к нему четыре десятичные цифры. Если мы хотим помечать предложения, то к меткам следует приписывать &SYSNDX. Приведенное выше макроопределение, таким образом, превращается в

При первом обращении к этому макро SAV5&SYSNDX будет иметь значение SAV50001, при втором — SAV50002 и т. д.

 
Статьи раздела