Макроязык АС. Руководство пользователя

Красноярский Государственный Университет
Фонд алгоритмов и программ
Регистрационный номер 009
01.03.84.
А.А. Бабий
Макроязык АС
Версия 2.0
Руководство пользователя

1. Введение

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

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

Примечание. Поскольку макроязык состоит из обычных макрокоманд, синтаксис записи макрокоманд (правила переноса и т.д.) в данном руководстве не описывается: см. руководство по языку ассемблера.

АС состоит из четырёх групп макрокоманд:

-обеспечение межмодульных связей:

INITM - войти в модуль

RETRN - вернуться из модуля

BCALL - вызвать модуль (подключенный реактором)

BLOAD -загрузить, вызвать и уничтожить модуль

Макрокоманды из этой группы обеспечивают: автоматическое базирование модуля; автоматическую организацию цепочки областей сохранения; автоматический приём, передачу и возврат параметров; автоматическое открытие и закрытие файла печати.

-Описание логики модуля:

BEGIN - начать блок

ENDD - завершить блок

DO -конструкция DO ... WHILE ...

WHILE -конструкция WHILE ... DO

IF - конструкция IF ... THEN ... ELSE ...

CASE -консрукция CASE ... OF ...

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

-Ввод-вывод:

@SBPVV - создать поле ввода-вывода с именем PVV

@SBPCR - создать DCB для печати

@SBCPK - создать DCB для ввода с карт

PRNT - напечатать строку

VKRT - считать карту

CONS - обеспечить диалог с оператором

BREAD - ввод блока из файла типа PO или PS

BWRITE - вывод блока из файла типа PO или PS

BCLOSE - закрытие PS-файла (CLOSE+FREEPOOL)

Макрокоманды из этой группы расширяют возможности системных макрокоманд ввода-вывода или упрощают работу с ними. Так, PRNT позволяет более удобно организовывать печать, CONS существенно расширяет возможности WTO или WTOR, BREAD - это просто READ и CHECK.

-Прочие макрокоманды:

MDAS - выполнение арифметических операций

BMVC - пересылка без указания длины

BSNAP - отладочные действия

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

Ниже приводится пример программы на языке АС.

Модуль PROBEL убирает лишние пробелы между словами. В результирующем поле слова должны разделяться ровно одним пробелом, перед первым словом пробела быть не должно.

Вызов: BCALL PROBEL, (POLE, LEN, LEN1)

Код возврата в регистре 15:

Результирующее поле распечатывается и выводится на консоль (в случае, если нет ошибок). Вывод производится по реальной длине (LEN1).

PROBEL START
INITM (12), POLE, LEN  - забазировались 12 регистром, приняли входные параметры
MVC KOD, =F'0'  код возврата - 0

- проверка длины
L 3, LEN
IF (C, 3, = F'2'), L, THEN, (MVC, KOD, = F '4'), RETURN
IF (C, 3, = F'80'), L, THEN, (MVC, KOD, = F '4'), RETURN

-сжатие (длина поля в регистре 3:
MVI SYM, C' ' поле SYM, содержащее предыдущий символ
LA 4, POLE адрес исходного поля
LA 5, POLE адрес результирующего поля

-цикл по счётчику в регистре 3:
DO PR1, (MVC, SYM, 0(4)), (АН,4,=H'1'), WHILE, (BCT,3)
PR1 IF (CLI, 0(4), 0' '),NE, THEN, (MVC,0 (1,5), 0 (4)), (AH,4,=H'1), ELSE, PR2
PR2 IF (CLI, SYM, C' '), NE, THEN, (MVC, 0(1,5), 0(4)), (AH, 4,=H'1')

-вычисляем реальную длину
DO (S, 5,=A(POLE)), (ST, 5, LEN1)

-если длина нуль, то ошибка
IF (LTR, 5, 5), E, THEN, (MVC, KOD,=F'8'), RETURN

-печать по длине в 5 регистре:
OPEN (@SBPR, OUTPUT)
PRNT ((5), POLE)

-вывод на консоль по длине в 5 регистре
CONS POLE,,(5)

-возврат, формируется код возврата, закрывается печать
RETURN EQU *
BCLOSE @SBPR
L 15, KOD
RETRN (80, POLE),, LEN1, RC=(15)

*

POLE DS CL80
KOD DS F
LEN DS F
LEN1 DS F
SYM DS C
@SBPVV
@SBPCR
END

2.0 Основные понятия языка АС

2.1. Символические имена

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

Однако, в макроязыке АС символическое имя часто имеет несколько иной смысл (не метка перехода, а имя вызываемого блока. Подробнее об этом будет сказан в 2.2)и кроме того, на имя накладываются некоторые дополнительные ограничения, а именно:

2.2. Блок

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

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

-непосредственное (физическое) вложение:
LA 3, ATABL адрес таблицы
L 4, KOLEL количество элементов
A1 здесь располагается тело цикла (вкладываемый оператор)
LA 3'1 (3) переход к следующему элементу
BCT 4, A1

-вложение вызовом:
LA 3, ATABL
L 4, KOLEL
A1 BAL 14, COMP
LA 3, 1(3)
BCT 4, A1
.......................
COMP подпрограмма, содержащая вкладываемый оператор
BR 14

В языке АС для вложения операторов обычно используется способ с вызовом. Точнее, если оператор или группа операторов оформляется блоком, то обратиться к нему можно, только вызвав его; при этом практически неважно, в каком месте программы он находится. Если же оператор не оформлен блоком, или реализуется обычными командами ассемблера, он вкладывается непосредственно.

Рассмотрим макрорасширение блока с именем, например COMP:

B END COMP
COMP тело блока (команды ассемблера и операторы АС)
BR14
ENDCOMP EQU *

Из примера видно, что вызвать блок COMP можно только командой BAL 14, COMP. Заметим, и это очень важно, что при непосредственном вложении блок не выполнится: сработает команда

B ENDCOMP

Отметим и то, что передача управления не по BAL (например, командой ВС) приведёт к ошибке: содержимое 14 регистра не определено; блок выполнится, но возврат не сработает.

Программист может организовывать блок двумя способами:

-большинство макрокоманд АС автоматически генерируют команды, необходимые для оформления блоком, если программист укажет для макрокоманды символическое имя, например:

IF (CLI, A, C'K'), E, THEN, RETURN

Не оформляется блоком, а

SR IF (CLI, A, C' K'), E, THEN, RETURN

Оформляется.

Программист может отказаться от организации блока, оставив, однако, имя:

SR IF (CLI, A, C' K'), E, THEN, RETURN, BLOK=N

В этом случае имя SR - обычное символическое имя ассемблера, на которое можно передать управление.

-группу команд и операторов АС можно оформить блоком при помощи макрокоманд BEGIN и ENDD

Например:

COMP BEGIN
ТЕЛО БЛОКА
ENDD COMP

Напишем теперь программу поиска в таблице на языке АС:

LA 3, ATABL
L 4, KOLEL
DO COMP, (LA, 3, 1(3)), WHILE, (BCT,4)
COMP BEGIN
ТЕЛО ЦИКЛА
ENDD COMP

Макрокоманда DO порождает цикл по счётчику в регистре 4. В этом цикле делается вызов блока COMP. После окончания цикла управление, как обычно в ассемблере, передаётся следующей команде, но это - макрокоманда BEGIN, т.е.

B ENDCOMP

, и блок COMР обходится, т.к. ENDCOMP - метка последней команды в ENDD.

Таким образом, логику программы на языке АС можно записать как совокупность блоков, вложенных друг в друга. Поскольку блок, оформленный с помощью BAGIN и ENDD, может содержать параметры, он может использоваться как внутренняя процедура (по терминологии ПЛ/1).

Приложение. Список операторов языка АС, автоматически оформляемых блоком:

BCALL, BLOAD, DO, WHILE, IF, CASE, PRNT, VKRT, CONS, BREAD, WRITE, BCLOSE, MDAS, BSNAP.

2.3. Машинная команда в АС-представлении

Макрокоманды описания логики обычно содержат в себе не только вызовы блоков, но и непосредственно команды ассемблера. Эти команды записываются специальным образом: вся команда заключается в скобки;

Например, команда SR 3,4 запишется так: (SR,3,4).

Приведём ещё несколько примеров:

(SVC, 34) (LA, 3, 8 (6,4)) (STM, 0, 15, SREG)

Отметим, что в таком виде нельзя записывать макрокоманды и псевдокоманды языка ассемблера, например, нельзя написать (GETMAIN, R, LV=800).

Примечание. Команды записываются в АС-виде только, если они состоят в макрокомандах описания логики, во всех остальных случаях они записываются в обычном виде.

2.4. Группа

Записывая логику при помощи макрокоманд АС, мы в макрокоманде можем указать одну или несколько команд, записанных в АС-виде, вызовы блоков, комментарии и средства выхода. Все эти элементы отделяются друг от друга и от ключевых слов запятыми.

Запись команд в АС-виде рассмотрена в 2.3. вызов блока осуществляется упоминанием его имени. Комментарии записываются в виде */текст/* (кроме АС-комментария внутри макрокоманды, может использоваться и обычный ассемблеровский комментарий). Средства выхода предназначены для преждевременного выхода из блока и имеют вид EXITИМЯ, где ИМЯ - имя блока. Если в группе присутствует средство выхода, блок с именем "ИМЯ" завершается, т.е. срабатывает возврат BR14. Если же макрокоманда, на которую ссылается средство выхода, имеет имя, но не оформлена блоком (BLOK=N), то управление передаётся следующей команде.

Пример групп в логических макрокомандах:

A DO DL, WHILE, (CR, 3, 5), NE
B DO A, WHILE, (CR, 8, 8), L, BLOK=N
SR 3,7
BL IF (CLI, A, C' * '), E, THEN, (LA, 3, 8(6,4)), *'ПЕРЕАДРЕСОВАЛИСЬ'*, *
BLK, EXITA, ELSE, EXTIB

В IF имеется три группы: группа условия (между IF и E), группа THEN (от THEN до ELSE), и группа ELSE (от ELSE до конца). Заметим разницу в использовании EXIT: EXITA вызывает BR 14 в блоке A, т.е. возврат в блок, вызвавший А (т.е. В). EXIT фактически передаёт управление команде, стоящей после блока В , т.е. SR 3,7.

2.5. Условия

В макрокомандах IF, DO, WHILE используется код условия. Он образуется просто из расширенной мнемоники команды ВС, а именно:

После команд сравнения:

Е-равно, L-меньше, Н-больше, NL - не меньше, NH - не больше

После арифметических команд:

Z - нуль, М - меньше нуя, Р - больше нуля, О - переполнение, NZ - не нуль, NM - не минус, NP - не плюс, NO - не переполнение.

После команды ТМ:

О - все 1, М - есть 1 и 0, Z - все 0, NO - не все 1, NM - все 1 или 0, NZ - не все 0.

Обычно в этих макрокомандах перед условием стоит команда сравнения. Но это не обязательно, например, можно написать

IF E, THEN , BLK1

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

3. Обеспечение межмодульных связей.

3.1. INITM

Макрокоманда автоматизирует действия, необходимые при входе в модуль.

3.1.1. Простейшее применение INITM

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

INITM (R1,...,RN)

Следом за START или CSECT (R1,...,RN - список базовых регистров), и все действия, необходимые для входа в модуль, будут выполнены: отведётся область сохранения программы, сохраняться общие регистры, организуется цепочка областей сохранения, объявятся и загрузятся базовые регистры.

Количество базовых регистров определяется просто: по одному на 4096 байт программы.

Примеры.

A START

INITM (12)

Программа занимает не более 4096 байт

MOD CSECT

INITM (9, 12)

Программа занимает не более 8192 байт. Базовые регистры 9 и 12.

3.1.2. Изменение имени области сохранения

Данная возможность используется только в многосекционных программах. Имя области сохранения, автоматически генерируемое INITM - @@@@SAVE. Если же в многосекционной программе несколько раз указать INITM, имя @@@@SAVE окажется определённым многократно. Чтобы избежать этого, в INITM имеется операнд SAVE, с помощью которого можно изменить имя области сохранения.

Всё вышесказанное относится также и к имени точки входа (по умолчанию @@@@IDNT). Соответствующий операнд - IDNT.

Пример.

A START
INITM (12)
..........
B CSECT
INITM (11), SAVE=SAVEB, IDNT=IDNTB

Внимание: если вход в секцию оформлен INITM с операндом SAVE, нужно внутри секции указывать параметр SAVE во всех макрокомандах BCALL, BLOAD, RETRN, так как они ссылаются на область сохранения.

3.1.3. Отказ от сохранения регистров

Данная возможность используется только, если программист хочет воспользоваться возможностями системной макрокоманды SAVE. INITM по умолчанию генерирует сохранение регистров так:

STM 14, 12, 12 (13)

Чтобы воспользоваться системной макрокомандой SAVE, нужно указать в INITM операнд REG=NO. Порядок команд будет такой:

START

SAVE (с нужными операндами)

INITM ..., REG=NO

3.1.4. Приём параметров

Данная возможность используется только тогда, когда модуль вызван другим модулем и нужно принять и разместить входные параметры. По стандартам IBM вызванному модулю передаётся список адресов параметров в регистре 1. Как правило, для удобства работы значения или адреса параметров переписываются во внутренние поля модуля, так как работать постоянно со списком параметров неудобно и неэффективно.

INITM избавляет программиста от рутинной работы по приёму параметров: можно указать в INITM список полей и/или регистров, в которые нужно разместить параметры или их адреса. При этом, если параметр принимать не нужно, его можно опустить.

3.1.4.1. Приём значения параметра в регистр

Соответствующий операнд INITM - номер регистра, заключённый в скобки; например, (5). Параметр, передаваемый из вызывающей программы, должен быть выровнен по границе полного слова, иначе возникнет прерывание по спецификации.

Пример.

INITM (12), (5), (10)

Модуль имеет два входных параметра: первый загружается в регистр 5, второй - в регистр 10 (12 регистр - базовый).

3.1.4.2. Приём адреса параметра в регистр

Соответствующий операнд INITM - *(R), где R - номер регистра, в который загружается адрес параметра.

Пример.

INITM (12), (5), *(10)

Первый параметр загружается в регистр 5, адрес второго параметра загружается в регистр 10.

3.1.4.3. Приём значения параметра в поле

Соответствующий операнд INITM - это имя поля, в которое передаётся параметр, например, АВС, или POLE4, или PRA+8.

Длина пересылаемых данных определяется, исходя из модификатора длины в команде DS или DC. Так, если поле PAR задано как

PAR DS CL 80

и указано

INITM (12), PAR

то перешлётся 80 байт.

Если же

PAR DS 8CL10

то перешлётся только 10 байт.

3.1.4.4. Приём адреса параметра в поле

Соответствующий операнд - имя поля, перед которым стоит звёздочка. Например:

INITM (12), *APAR

Поле не обязательно должно быть выровнено по границе слова.

3.1.4.5. Прочие требования
3.1.4.6. Пример

INITM (3, 4, 5), A, *B, (6),,*(8)

Для базирования отводятся регистры 3, 4, 5. Первый параметр передаётся в поле А, адрес второго - в поле В, третий загружается в регистр 6, четвёртый пропускается, адрес шестого параметра загружается в регистр 8.

3.1.4.7. Резюме.

Макрокоманда INITM имеет следующий вид:

INITM (база)[,список параметров][,REG=NO][, SAVE=имя][,IDNT=имя]

3.2. RETRN

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

3.2.1.Простейшее применение

Если вход в модуль был оформлен с INITM, то, чтобы выйти из него, достаточно написать

RETRN

Восстановится содержимое регистров 14-12 и возвратится управление вызывающему модулю.

3.2.2. Изменение имени области сохранения

Для успешного возврата RETRN должна знать адрес области сохранения. По умолчанию считается, что имя области сохранения @@@@SAVE, т.е. определённое по умолчанию в INITM. Если же в INITM имя другое, нужно указать операнд SAVE=ИМЯ с тем же именем, что и в INITM.

3.2.3. Восстановление регистров и возврат управления

Возможно, пользователь захочет воспользоваться возможностями системной макрокоманды RETURN (например, восстановлением части регистров). В то же время ему нужны возможности RETRN по возврату параметров.

Указав RET=NO в макрокоманде RETRN, пользователь возвратит значения параметров в вызывающий модуль, но собственно возврат управления и восстановление регистров не произойдёт.

3.2.4. Возврат значений параметров

Подход, принятый в языках программирования высокого уровня (принимаются только адреса параметров), не всегда удобен при программировании на языке ассемблера. Поэтому INITM может принимать не только адреса параметров, но и их значения, однако, при возврате управления нужно тогда вернуть и значения параметров, макрокоманда RETRN представдяет возможности по возврату параметров, аналогичные возможностям INITM по примеру параметров.

Возвращаемые параметры перечисляются в поле операндов макрокоманды RETRN. Операнд может указать только возвращаемый параметр (и тогда длина поля считается равной четырём), либо имеет вид (длина, параметр). Если параметр возвращать не нужно, то соответствующий операнд опускается (например, RETRN ,,,А возвращает только 4 параметр)

Длина возвращаемого параметра не может быть больше 255.

3.2.4.1. Возврат литерала

Соответствующий операнд - просто литерал, например, =F'4'. Если литерал имеет длину, не равную 4 байтам, указывается длина, например:

RETRN=F'5', (20,=CL20'ЭТО СИМВОЛЬНЫЙ ЛИТЕРАЛ')

3.2.4.2. Возврат содержимого поля

Соответствующий операнд - имя поля, например, АВС. Если возвращаемый параметр имеет длину, не равную 4, нужно указать длину, адрес поля может быть задан в виде D(B), например 154(9), т.е. возвращаемый параметр находится по адресу в регистре 9 плюс 154 байта.

3.2.4.3. Возврат содержимого регистра

Соответствующий операнд - номер регистра, заключённый в скобки, например, (6). Соответствующий параметр в вызываемой программе должен быть выровнен по границе слова.

3.2.4.4. Возврат параметра, адрес которого в поле

Соответствующий операнд имеет вид *ИМЯ, где ИМЯ - имя поля, содержащего адрес пересылаемых данных. Поле, содержащее адрес, должно быть выровнено по границе слова, операнд может иметь вид *D(B). Если длина возвращаемых данных не равна четырём, следует указать длину.

3.2.4.5. Возврат параметра, адрес которого - в регистре

Соответствующий операнд - *(R), где R - номер регистра, содержащего адрес пересылаемых данных.

3.2.4.6. Пример применения макрокоманды RETRN

RETRN ,,(2), (40,*(3)), BC, *KOL+48, (200, 3(8))

Значения первого и второго параметров не возвращаются, третий параметр - содержимое регистра 2 (4 байта), четвёртый - 40 байт по адресу, содержавшемуся в регистре 3, пятый - 4 байта KOL+48 и седьмой - 200 байт по адресу, содержащемуся в регистре 8, плюс 3.

3.2.4.7. Код возврата

Программист может указать код возврата, который RETRN поместит в регистр 15. Соответствующий операнд может быть записан как RC=(15), и тогда будет использовано текущее значение регистра 15, или же RC=N, где N - целое число, например RC=4.

3.2.4.8. Резюме

Макрокоманда RETRN имеет следующий вид:

[имя] RETRN [параметры][RET=NO][SAVE=ИМЯ][RC=код]

3.3.BCALL

Макрокоманда BCALL автоматизирует действия, необходимые при вызове модуля по стандартам IBM.

3.3.1. Простейшее применение

Вызов модуля без параметров:

BCALL имя

Например, BCALL SUBPROG

3.3.2. Задание адреса модуля

Не всегда вызывающему модулю доступно имя точки входа в вызываемый модуль, часто известен только его адрес (например, если модуль был загружен командой LOAD или адрес модуля извлечён из таблицы адресов модулей). Макрокоманда BCALL позволяет задать адрес модуля либо в регистре, либо в поле. Примеры:

BCALL (8) адрес модуля находится в регистре 8

BCALL *APROG адрес модуля находится в поле APROG

BCALL *4(11) адрес модуля находится в поле по адресу в 11 регистре, плюс 4.

BCALL может вызывать не только внешние модули, но и блоки. Это необходимо, если блоку нужно передавать параметры. Перед именем блока указывается символ =, например:

BCALL = BLK1, (PAR1, PAR2)

3.3.3.Передача параметров

Если вызываемый модуль или блок имеет параметры, список параметров заключается в скобки; в списке параметры перечисляются через запятую. Список параметров отделяется от имени модуля (или адреса, или имени блока) запятой.

3.3.3.1. Параметр находится в поле

Соответствующий операнд - имя поля, например:

BCALL PROG, (POLE)

3.3.3.2. Параметр находится в регистре

Соответствующий операнд имеет вид (R), где R - номер регистра, например:

BCALL PROG, ((4))

Внутри макрокоманды заводится полное слово, в которое выгружается имя регистра. Если параметр возвращаемый, то после BCALL в этом регистре будет возвращённое значение параметра, иначе же содержимое регистра не изменится.

3.3.3.3. Адрес параметра находится в регистре

Соответствующий операнд - *(R), где R - номер регистра, содержащего адрес параметра, например:

BCALL PROG,(*(5))

3.3.3.4. Адрес параметра находится в поле

Соответствующий операнд - *ИМЯ, где ИМЯ - имя поля, содержащего адрес параметра, например:

BCALL PROG, (*APARAM)

3.3.3.5. Параметр - литерал

Соотетствующий операнд - литерал, например:

BCALL PROG, (=F'128',=CL64'MESSAGE',=H'0')

3.3.3.6. Адрес параметра задан в виде D(X,B)

Соответствующий операнд имеет вид #D(X,B), где D - смещение, X - индексный регистр, В - базовый регистр, например:

BCALL PROG, (#128(3,6))

3.3.4. Изменение имени области сохранения

По умолчанию BCALL считает, что имя области сохранения @@@@SAVE. Если это не так, нужно указать параметр SAVE=ИМЯ.

3.3.5. Код условия

Регистр 15 при выходе из BCALL содержит код возврата, сформированный вызываемым модулем.

3.3.6. Обработка файла печати

Если модули ведут печать на один SYSPRINT, то нужно каждый раз перед вызовом модуля закрывать файл @SBPR (если используется PRNT), а после возврата открывать его заново. При этом нужно сохранять значение кода возврата и т.д. Всё упрощается, если указать операнд PR=Y. Тогда @SBPR автоматически закроется перед вызовом модуля и автоматически откроется после вызова, регистр 15 по-прежнему содержит код возврата.

3.3.7. Резюме

Макрокоманда BCALL имеет вид:

[ИМЯ] BCALL ПРОГ [, (параметры)][,SAVE=ИМЯ][,PR=Y][,BLOK=N]

Имя - не более 4 символов. ПРОГ - указание имени или адреса программы, параметры - список параметров, который может отсутствовать, SAVE указывает имя области сохранения, PR=Y позволяет автоматически открыть-закрыть @SBPR. BLOK=N указывается, если BCALL должен иметь имя, но не должен оформляться блоком.

3.4. BLOAD

Макрокоманда BLOAD загружает модуль, вызывает его, а затем уничтожает. Фактически BLOAD эквивалентна последовательности макрокоманд: LOAD, BCALL, DELETE. По синтаксису и возможностям BLOAD полностью аналогична BCALL, за двумя исключениями:

4. Макрокоманды описания логики

4.1. BEGIN

4.1.1. Простейшее применение

Чтобы организовать вход в блок, достаточно написать имя BEGIN

Длина имени - не более 4 символов, организуется обход блока, сохранения регистра 14 (область сохранения регистра 14 отводится автоматически внутри BEGIN).

4.1.2. Запись группы

В макрокоманде BEGIN можно записать группу, например:

BLK BEGIN (ST, 0, SIM,*' ЗАПОМНИЛИ 0',BLK2

4.1.3. Приём параметров

Если в блок передаются параметры, то они указываются после служебного слова PARAM**. Служебное слово PARAM** указывается либо первым операндом BEGIN, либо после группы, если она есть. Возможности и синтаксис приёма параметров такие же, как и у макрокоманды INITM (см. 3.1.4.). Примеры:

MIT BEGIN (ST, 0, SIM), PARAM**, *(3), ABC, (8)

BLP1 BEGIN PARAM**, POLE+4, *ABC, (11)

4.1.4. Сохранение регистров

Иногда требуется, чтобы блок не портил содержимое общих регистров, тогда в BEGIN и ENDD соответствующего блока указывается параметр SAVE=YES, и регистры 1-15 сохраняются в области сохранения, автоматически создающейся в BEGIN.

Примеры:

A BEGIN SAVE=YES

B BEGIN (MVC, D, K), SAVE=YES

4.1.5. Резюме

Макрокоманда BEGIN имеет вид:

ИМЯ BEGIN [ГРУППА][PARAM**, ПАРАМЕТРЫ][SAVE=YES]

4.2. ENDD

4.2.1.Простейшее применение

Чтобы закончить блок, достаточно написать

ENDD ИМЯ

Где ИМЯ - имя блока, например:

ENDD BLO

4.2.2. Возврат параметров

Возвращаемые параметры, если они есть, записываются после имени закрываемого блока. Возможности и синтаксис возврата параметров полностью совпадают с возможностями и синтаксисом макрокоманды RETRN (см. 3.2.4.). Пример:

ENDD BLP, (8),,AB

4.2.3. Восстановление регистров

Если в макрокоманде BEGIN соответствующего блока было указано SAVE=YES, обязательно нужно указать SAVE=YES и в ENDD. Нельзя указывать SAVE=YES в ENDD, если оно не было указано в BEGIN.

4.2.4. Резюме

Макрокоманда ENDD имеет вид:

ENDD ИМЯ [,ПАРАМЕТРЫ][SAVE=YES]

4.3. DO

Как правило, DO используется для создания конструкции DO ... WHILE ..., т.е. цикла, в котором сначала выполняется тело цикла, а затем - проверка. Если же WHILE не указано, то генерируется не цикл, а линейная последовательность (СР, с оператором DO в PL/1)

4.3.1. Простейшее применение

Макрокоманду DO можно использовать для генерации группы. Например, DO (L, 4, ABUF),(ST, 8, ABB),PLT,*' вызов блока PLT'

4.3.2. Цикл по счётчику

Загрузив в некоторый регистр число повторения цикла, мы можем организовать цикл по счётчику, например:

LA 5, 100

DO (L, 4, ABUF), PLT, WHILE,(BST, 5)

Здесь WHILE - служебное слово, означающее, что нужно делать. Цикл, А (ВСТ, 5) указывает, что цикл нужно организовывать по счётчику, находящемуся в регистре 5.

Между WHILE и (ВСТ, R) может быть любая группа.

4.3.3. Цикл по условию

Условие формируется группой, стоящей после WHILE. Используется код условия, полученный последней командой группы (или последней командой блока в группе).

Об условиях см. 2.5.

Пример:

DO (L, 4, ABUF), PLT, WHILE, (CLI, POLE, C'*'), NE

Тело цикла (группа между DO и WHILE) будет выполняться, пока условие истинно.

4.3.4. Бесконечный цикл

Бесконечный цикл организуется, если после WHILE не указаны ни группа, ни условие. Выход из такого цикла может быть организован либо EXIT - средствами, либо по прерыванию (например, по концу файла). Пример:

DO PLT, (L, 3, 0, (3)), WHILE

4.3.5. Оформление блоком

Если макрокоманда DO имеет имя, она автоматически оформляется блоком, если оформление блоком нежелательно, следует указать BLOK=N.

Блок не нужен в двух случаях:

4.3.6. Прочие соображения

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

4.3.7. Резюме

Макрокоманда DО имеет вид:

[ИМЯ] DO группа [,WHILE[группа], условие][BLOK=N]

4.4. WHILE

Макрокоманда WHILE создаёт конструкцию WHILE... DO..., то есть конструкцию цикла, в которой проверка условия выполняется перед телом цикла, в которой проверка условия выполняется перед телом цикла, макрокоманда имеет вид:

[ИМЯ] WHILE [ГРУППА,] УСЛОВИЕ, DO, ГРУППА[,BLOK=N]

Об условии см. 2.5. Тело цикла выполняется, если условие истинно. Пример:

WHILE (CLI, POLE, C'*'), NE, DO, (L, 4, ABUF), PLT

Этот оператор отличается от оператора из 4.3.3 : там, если в POLE *, тело цикла всё же проработает один раз, а здесь - нет.

4.5. IF

Макрокоманда IF порождает конструкцию двоичного выбора:

[ИМЯ] IF [группа,], условие, THEN, группа [ELSE, группа][,BLOK=N]

Об условии см. 2.5. Если условие истинно, срабатывает группа, стоящая после THEN, иначе - группа, стоящая после ELSE.

4.6. CASE

Макрокоманда CASE порождает конструкцию множественного выбора:

[ИМЯ] CASE [ГРУППА,], (СРАВНЕНИЕ),(КЛЮЧ1,..., КЛЮЧN[,#ELSE]),OF,ГРУППА1,#..., ГРУППАN[,#,ГРУППА ELSE][,BLOK=N]

Сравнение состоит из команды сравнения и первого сравниваемого, например (CLI,A)

Ключи - это набор вторых сравниваемых, например:

(C'1', C'2', C'3') или (B, C, D, E)

Группа с номером К срабатывает, если сравнимое совпало с ключом номер К.

Если сравниваемое не совпало ни с одним ключом, можно выполнить группу #ELSE.

CASE (CLC, A),(=C'11',=C'12',=C'13',#ELSE), OF, (MVC, DK, K),#,PPP,(LA, 5, 8), #, G,@,ERRR

Если А=С'11' то выполняется MVC DK, K

Если А=С'12' то выполнятся блок PPP и LA 5, 8

Если А=С'13' то выполняется блок G

Если А не совпало ни с одним ключом, выполняется блок ERRR.

5. Макрокоманды ввода-вывода

Макрокоманды ввода-вывода на языке АС служат для того, чтобы в сжатой форме описывать наиболее часто употребляемые операции ввода-вывода.

Так, @SBCPK и @SBCPR просто порождают DCB для ввода с перфокарт и печати с наиболее часто употребляемыми параметрами;

BREAD совмещает зануление DECB, READ, CHECK; PRNT и CONS расширяют возможности системных макрокоманд PUT и WTOR.

5.1. @SBPVV

Макрокоманда создаёт поле ввода-вывода длиной 12 байт, с именем PVV. Это поле используется по умолчанию командами VKRT, PRNT, CONS. Кроме поля PVV, создаются рабочие поля, необходимые для PRNT.

Поскольку @SBPVV не создаёт выполняемых команд, её необходимо ставить среди описаний (т.е. DS, DC, и т.д.)

Макрокоманда имеет вид:

@SBPVV

5.2. @SBCPR

Макрокоманда создаёт DCB для печати. Имя DCB @SBPR, приняты значения DSORG=PS, MACRF=PM, BLKSIZE=128. Имя DO по умолчанию SYSPRINT, однако его можно менять параметром DD.

Макрокоманд имеет вид:

SBCPK [DD=ИМЯDD]

5.3. @SBCPK

Макрокоманда создаёт DCB для ввода с карт с именем @SBPK. DSORG=PS, MACRF=GM, BLKSIZE=80. DDNAME и EODAD можно менять параметрами DD и END соответственно:

@SBCPK [END=метка выхода по концу файла][DD=ИМЯ DD]

5.4. BCLOSE

Макрокоманда закрывает наборы данных QSAM. Есть два отличия от обычной команды CLOSE:

Макрокоманда имеет вид:

[ИМЯ] BCLOSE DCB1[,DCB2...][BLOK=N]

Где DCB - это имя DCB или (R), где R - номер регистра

5.5. BREAD и BWRITE

При работе с BSAM, чтобы выполнить чтение или запись, нужно записать три команды: нуление DECB, READ или WRITE и CHECK. Если CHECK выполняется сразу за чтением или записью, удобнее объединить эти три команды. Это и делают макрокоманды BREAD и BWRITE. Более того, они автоматически порождают уникальные имена DECB.

[ИМЯ] BREAD ИМЯФАЙЛА, АДРЕСЗАПИСИ, ДЛИНА [,BLOK=N]

[ИМЯ] BWRITE ИМЯ ФАЙЛА, АДРЕСЗАПИСИ, ДЛИНА[,BLOK=N]

Правила записи имени файла, адреса запись и длины такие же, как у WRITE и READ.

5.6. VKRT

Макрокоманда обеспечивает ввод карты.

[ИМЯ] VKRT [DCB=ИМЯ][P=ИМЯ][BLOK=N]

По умолчанию имя DCB - @SBPK, т.е. порождённое макрокомандой @SBCPK. Однако, если имя другое или доступен только адрес DCB, пользователь должен поместить адрес DCB в поле и имя этого поля указать в параметре DCB.

По умолчанию карта вводится в поле PVV, определяемое макрокомандой. При желании программист может задать адрес поля в символическом виде или в виде (R), где R - номер регистра, содержащего адрес поля. Для этого используется параметр Р.

Программист сам открывает и закрывает файл ввода.

5.7. PRNT

Макрокоманда автоматизирует процесс формирования строки для печати. Если используется PRNT, обязательно должно быть определено поле PVV посредством макрокоманды @SBPVV.

5.7.1. Простейшее применение

Написав

PRNT

Мы просто распечатываем поле PVV.

5.7.2. Очистка PVV

PVV зачищается пробелами по команде

PRNT SKIP=0

5.7.3. Печать по списку

PRNT позволяет собрать выводную строку из нескольких элементов. Элементы перечисляются через запятую и могут быть:

-символическим именем

Если длина подстроки, определяемой элементом, равна модификатору длины в DС или DS, указывается просто имя, например, ABC или RP*10, иначе пользователь сам может указать длину: (длина, имя). Например, (13, АВС).

-литералом

Литерал должен быть символьным. Способ указания длины - такой же, как и для символического имени, но, если в литерале есть модификатор кратности, длина должна указываться обязательно. Примеры:

=C'ЭТО ЛИТЕРАЛ', (15,=15C'*')

-указанием адреса: (длина, адрес), например: (28,3(4)). Длина в этом случае указывается обязательно.

Пример печати списка:

PRNT=C'X=',(3,POLE),(8,0(6)),(30,=30C'*'),POLE+9

5.7.4. Дублирование строк

Параметр SKIP позволяет распечатать строку требуемое количество раз. Например, PRNT SKIP=12 пропускает 12 пустых строк, а PRNT (128,=128C'*'),SKIP=3

Печатает три строки звёздочек.

5.7.5. Печать со смещением

Иногда требуется печатать строку не с первой позиции. Это достигается использованием параметра S. Например, чтобы напечатать 'пример' с тридцатой позиции, нужно указать:

PRNT=C'ПРИМЕР',S=30

5.7.6. Изменение имени DCB

По умолчанию PRNT считает, что работает с DCB, имеющим имя @SBPR, однако, если имя другое или доступен только адрес DCB, используется параметр DCB точно так же, как в VKRT.

5.7.7. Дополнительная информация

Следует помнить, что PRNT со списком или SKIP, не равным нулю, перед заполнением строки зачищает PVV пробелами. Поэтому, во-первых, в PVV не следует хранить информацию, а во-вторых, зачищать PVV перед печатью не нужно.

Программист сам открывает и закрывает файл печати,

( OPEN(@SBPR, OUTPUT) BCLOSE @SBPR ).

5.7.8. Резюме

[ИМЯ] PRNT [СПИСОК][SKIP=KRATH,][S=СМЕЩЕНИЕ][DCB=ИМЯ][BLOK=N]

5.8. CONS

Макрокоманда CONS обеспечивает дополнительные возможности по связи с оператором.

5.8.1. Простейшее применение

CONS может работать как WTO, но, кроме литерала, можно передать поле:

CONS=C'СООБЩЕНИЕ'

CONS POLEA

5.8.2. Указание длины сообщения

В предыдущем примере длина передаваемого поля определялась модификатором длины в DS или DС. Можно, однако, указать требуемую длину либо непосредственно в CONS, либо загрузив её в регистр:

CONS POLE,,3 выводит 3 байта из POLE

CONS POLE,,(3) выводит поле по длине в R3

Если длина находится в регистре, обязательно нужно указать операнд LMAX=N, где N - максимальная длина сообщения.

Вообще, следует помнить, что длина сообщения должна быть не более 255 символов.

Примечание. Сообщение можно передавать не только литералом или символическим именем, но и задавая адрес, например:

CONS 0(6),,(7)

В данном примере адрес сообщения в 6 регистре, длина - в 7.

5.8.3. Запрос ответа

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

CONS=C'ОТВЕТЬ',8 ответ - 8 байт

LA 8, 12

CONS=C'ОТВЕТЬ',(8) длина ответа в регистре 8

5.8.4. Изменение имени поля ответа

По умолчанию ответ помещается в поле PVV. Если программиста это не устраивает, он может сменить имя, используя параметр Р:

CONS=C'ОТВЕТЬ',(9),P=ANSW

5.8.5. Резюме

Макрокоманда CONS имеет вид

[ИМЯ] CONS СООБЩЕНИЕ [ДЛИНА ОТВЕТА][Р=ИМЯ][MAX=ДЛИНА][BLOK=N]

6. Прочие макрокоманды

6.1. BMVC

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

BMVC PVV,=C'СООБЩЕНИЕ'

Эквивалентно

MVC PVV(9),=C'СООБЩЕНИЕ'

6.2. MDAS

Для того, чтобы сложить два числа, находящиеся в памяти, требуется как минимум три команды: ЗАГРУЗИТЬ, СЛОЖИТЬ, ЗАПИСАТЬ. Если же слагаемое находится в однобайтовом поле, нужно ещё предварительно очистить регистр. Если подобных операций в программе много, удобнее воспользоваться макрокомандой MDAS:

[ИМЯ] VDAS КОД, АД1, АД2[T1=ТИП1][Т2=ТИП2][BLOK=N]

КОД - код операции: А - сложение, S - вычитание, М - умножение, D - деление.

АД1 - адрес первого операнда, например KOL 0(3,8)

АД2 - адрес второго операнда или литерал

Т1 - тип первого операнда. Если не указан, первый операнд занимает слово с фиксированной точкой. Т1=Н - операнд занимает полуслово с фиксированной точкой, Т1=С - операнд занимает 1 байт.

Т2 - тип второго операнда. Значения - аналогично Т1.

Результат операции заносится в первый операнд.

Примеры:

MDAS A,KOLKS,=F'1' прибавили к слову KOLKS единицу

MDAS M, KOLKS,=F'6',T1=H умножили полуслово KOLKS на 6

MDAS D, KK, 0(3), T2=C разделили слово КК на содержимое байта, адрес которого в R3

Примечание. При делении частное заносится в первый операнд, остаток - в регистр 0.

6.3. BSNAP

Макрокоманда предназначена для облегчения отладки программ, написанных на языке ассемблера

6.3.1. Порождение, открытие и закрытие DCB

Макрокоманда BSNAP DCB=YES порождает DCB с именем @@@@SNAP для макрокоманд SNAP и BSNAP и автоматически открывает его. Порождаются рабочие поля для BSNAP.

Макрокоманда BSNAP CLOSE=YES закрывает DCB @@@@SNAP, в секции или группе секций, ассемблируемых вместе, можно только один раз указать BSNAP c DCB=YES. При желании после закрытия @@@@SNAP пользователь может открыть его повторно:

OPEN (@@@@SNAP, OUTPUT)

По умолчанию имя DD в @@@@SNAP - SNAPDD, однако его можно изменить операндом DD, например:

BSNAP DCB=YES, DD=OTL

6.3.2. Обработка программных прерываний

Работая в ОС MVT, программист не получает индикативного дампа. Единственное, что он имеет - код прерывания, выдача же дампа по SYSABEND или SYSUDUMP приводит к перерасходу бумаги. BSNAP позволяет автоматически получить информацию о координатах команды, вызвавшей командное прерывание. Для этого, кроме DCB=YES, следует указать INTR=YES, выдастся дамп области из 24 байтов.

Программа прекращает работу с кодом завершения USER=4095, код прерывания можно узнать из PSW.

Макрокоманда BSNAP CLOSE=YES закрывает DCB и восстанавливает предыдущий адрес программы обработки ошибок.

6.3.3. Выдача отладочных дампов

В процессе отладки иногда требуется выдать на печать определённые области оперативной памяти. Обычно для этого используется макрокоманда SNAP. Однако она в ряде случаев неудобна для использования. BSNAP использует команду SNAP, но имеет более гибкий механизм задания границ распечатываемой области.

Чтобы выдать дамп, обязательно нужно указать операнд А1 в макрокоманде BSNAP, который указывает на начало области. Адрес начала области может быть задан:

Например, А1=*ADDR или A1=*2(7)

Верхняя граница области может быть задана двумя способами:

Если, кроме области, нужно выдать ещё и содержимое регистров, следует указать операнд REGS=YES в макрокоманде BSNAP. Номер дампа указывается операндом ID (например, ID=5)

По умолчанию регистры не печатаются, ID=1.

Макрокоманда BSNAP имеет возможность не генерироваться, даже если она указана. Это бывает удобно, если нужно исключить режим отладки, не убирая отладочных команд. Для этого нужно первыми двумя картами программы поставить

GBLS &TEST

&TEST SETC 'HET'

6.3.4. Резюме

[ИМЯ] BSNAP [DCB=YES][INTR=YES][DD=ИМЯ DD][CLOSE=YES][A1=АДРЕС][A2=АДРЕС][LN=ДЛИНА][REGS=YES][ID=НОМЕР][BLOK=N]


© Алексей Бабий 1980