                          Макроассемблер  M80
                          =================== 

                               Содержание

        1         Назначение и условия применения макроассемблера.....
        2         Элементы и основные конструкции языка...............
        2.1       Основные элементы языка.............................
        2.1.1     Символы.............................................
        2.1.2     Числа, константы и строки...........................
        2.1.3     Символические имена.................................
        2.2       Выражения...........................................
        2.2.1     Арифметические и логические операции................
        2.2.2     Абсолютные и перемещаемые имена.....................
        2.2.3     Внешние ссылки......................................
        2.3       Синтаксис ассемблерных предложений..................
        2.3.1     Метка...............................................
        2.3.2     Оператор............................................
        2.3.3     Операнды и примечания...............................
        2.4       Псевдокоманды.......................................
        2.4.1     Псевдокоманды перемещения...........................
        2.4.1.1   ASEG................................................
        2.4.1.2   COMMON..............................................
        2.4.1.3   CSEG................................................
        2.4.1.4   DSEG................................................
        2.4.2     DB - определить байт................................
        2.4.3     DC - определить символ..............................
        2.4.4     DS - определить область.............................
        2.4.5     DW - определить слово...............................
        2.4.6     END.................................................
        2.4.7     ENTRY/PUBLIC........................................
        2.4.8     EQU.................................................
        2.4.9     EXT/EXTRN...........................................
        2.4.10    INCLUDE.............................................
        2.4.11    NAME................................................
        2.4.12    ORG - задать счетчик адреса.........................
        2.4.13    PAGE................................................
        2.4.14    ASET................................................
        2.4.15    TITLE...............................................
        2.4.16    SUBTTL..............................................
        2.4.17    .COMMENT............................................
        2.4.18    .PRINTX.............................................
        2.4.19    .RADIX..............................................
        2.4.20    .REQUEST............................................
        2.4.21    Условные псевдокоманды.............................
        2.4.21.1  ELSE...............................................
        2.4.21.2  ENDIF..............................................
        2.4.23    Перемещение перед загрузкой........................
        2.5       Макрокоманды и блоки...............................
        2.5.1     Терминология.......................................
        2.5.2     Блок REPT-ENDM.....................................
        2.5.3     Блок  IRP-ENDM.....................................
        2.5.4     Блок IRPC-ENDM.....................................
        2.5.5     MACRO..............................................
        2.5.6     EXITM..............................................
        2.5.7     LOCAL..............................................
        2.5.8     Специальные макрооператоры и формы.................
        3         Руководство по эксплуатации компилятора M80........
        3.1       Обращение к компилятору. Входные и выходные данные.
        3.2       Опции компиляции...................................
        3.3       Формат листинга....................................
        3.4       Сообщения об ошибках...............................



             1. Назначение и условия применения макроассеблера 

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


             2. Элементы и основные конструкции языка 

             2.1. Основные элементы языка

             2.1.1. Символы

             Все сложные элементы языка М80 формируются из символов.
        В качестве символов могут использоваться:
             - буквы латинского алфавита от A до Z
             - цифры от 0 до 9
             - специальные символы + - , : ; ( ) ' # $ пробел ;


             2.1.2. Числа, константы и строки
      
             Числа - это беззнаковые 16-битные величины.  Число всегда
        вычисляется в системе счисления по умолчанию,  если оно не за-
        дано в специальном виде:

            nnnnnnnnB            - двоичное (где n - 0 или 1)

            nnnnO или nnnnQ      - восьмеричное (где n - 0..7)

            nnnnH или nnnnX      - шестнадцатиричное (где n - 0..9,
                                   A,B,C,D,E,F), если первый символ не
                                   цифра, то перед ним должен стоять 0
                                   0nnnnH или 0nnnnX

             По умолчанию все числа  считаются  в  десятичной  системе
        счисления. Этот режим можно изменить. С помощью команды .RADIX
        можно  выбрать  любое основание системы счисления  от 2 до 16.
        Переполнение при вычислении числа игнорируется и значащими яв-
        ляются младшие 16 бит.
             Символьная константа  -  это строка,  содержащая один или
        два символа в апострофах.
             Значением символьной  константы,  содержащей один символ,
        является величина численного значения  соответствующего  кода,
        принятого  в  операционной системе (ОС).  Например,  значением
        константы "A" будет 41h.
             Значением символьной  константы,  содержащей два символа,
        будет двухбайтовое число,  причем в старшем байте будет значе-
        ние  первого  символа,  а  в  младшем байте - значение второго
        символа.  Например,  значением  константы  "AB"  будет  число
        41h*256+42h.
             Строка - это набор символов,  заключенных в  кавычки  или
        апострофы.  Кавычки также могут быть элементом строки,  но при
        этом они должны удваиваться. Например, предложение

                DB "Я""ИДУ""ГУЛЯТЬ"

        запомнит строку

               Я"ИДУ"ГУЛЯТЬ

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


             2.1.3. Символьные имена (метки)

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

        В именах допустимы следующие символы:

             буквы от A до Z, цифры от 0 до 9, $ . ? @

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


             2.2. Выражения

             2.2.1. Арифметические и логические операции

             В выражениях допустимы следующие операции, приведенные в
        порядке убывания приоритета их выполнения.

                NUL
                LOW, HIGH
                *, /, MOD, SHR, SHL
                Унарный минус
                +, -
                EQ, NE, LT, LE, GT, GE
                NOT
                AND
                OR, XOR

             Для изменения порядка выполнения операций надо  использо-
        вать скобки. При вычислении выражений сначала выполняются опе-
        рации,  имеющие более высокий приоритет.  Все подвыражения,со-
        держащие  операции с более высоким приоритетом,  вычисляются в
        первую очередь.
             Все операции, кроме +,  -, *, /, должны быть отделены от
        операндов по крайней мере одним пробелом.  Операции  выделения
        байта HIGH, LOW выделяют старшие или младшие 8 бит из абсолют-
        ной 16-битной величины.  Если в качестве операнда используется
        перемещаемая величина, то HIGH и LOW интерпретируются как опе-
        рации, работающие с адресом ноль.


             2.2.2. Абсолютные и перемещаемые имена

             Все символические имена,  используемые в качестве операн-
        дов в выражениях,  есть либо абсолютные имена, либо перемещае-
        мые  имена.  Перемещаемые  имена подразделяются на программные
        перемещаемые имена,  перемещаемые имена данных  и  COMMON  (п.
        2.4.1.).
             Все символические имена,  ассемблированные для  псевдоко-
        манд ASEG (по умолчанию),  CSEG или DSEG, относятся к абсолют-
        ным,  перемещаемым программным или перемещаемым  данным  соот-
        ветственно. Количество имен COMMON в программе зависит от чис-
        ла блоков COMMON,  поименованных в программе с помощью псевдо-
        команды COMMON.  Два символических имени COMMON считаются раз-
        ными, если они присутствуют в разных блоках COMMON.
             При любой операции, кроме сложения и вычитания, оба опе-
        ранда должны быть абсолютными.
             Для сложения применяются следующие правила:

        1) по крайней мере один из операндов должен быть абсолютным; 
        2) абсолютное + перемещаемое = перемещаемое

             Для вычитания действуют правила:

        1) перемещаемое - абсолютное = перемещаемое
        2) перемещаемое - перемещаемое = абсолютное

             Причем в 2) оба имени должны быть перемещаемыми именами
        одного типа.
             Для каждого  промежуточного шага при вычислении выражения
        должны выполняться вышеуказанные правила,  иначе будет  выдано
        сообщение об ошибке. Например, если FOO, BAZ и ZAZ - три симво-
        лических перемещаемых имени, то выражение:

                FOO + BAZ - ZAZ

             выработает сообщение об ошибке, т.к. на первом шаге будут
        складываться два перемещаемых имени. Этого можно избежать, ис-  
        пользуя скобки:
  
                FOO + (BAZ - ZAZ)


             2.2.3. Внешние ссылки

             Символическое имя  может  быть  внешним  (EXTRN)  или нет
        (см.п. 2.2.9.). Внешнее имя ассемблируется в 2 байта.  При ис-
        пользовании  внешних имен в выражениях должны выполняться сле-
        дующие правила:

        1) EXTRN допустимы только при сложении и вычитании;
        2) если в выражении используется имя типа EXTRN, 
           то результат всегда будет EXTRN;
        3) при сложении любой операнд (но не оба одновременно)
           может быть EXTRN;
        4) при вычитании только первый операнд может быть EXTRN.


             2.3. Синтаксис ассемблерных предложений

             Ассемблерная программа состоит из последовательности
        предложений. Каждое предложение имеет следующую структуру:

                метка: (оператор) (операнды)  ;примечание

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


             2.3.1. Метка

             Метка -  это  символическое  имя,  после которого следует
        двоеточие.  Если метка присутствует, то она должна быть первым
        элементом  предложения.  Значение  метки есть текущее значение
        счетчика адреса. Если после метки стоят два двоеточия "::", то
        такая метка объявляется глобальной (PUBLIC) и к ней можно обра-
        щаться из другой программы.
 

             2.3.2. Оператор

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

                1) мнемокод микропроцессора Z80 (I8080);
                2) макровызов;
                3) псевдокоманда;
                4) выражение.

             Если в поле оператора стоит выражение, то ассемблер расс-
        матривает его как псевдокоманду DB.


             2.3.3. Операнды и примечания

             Следующим элементом предложения являются операнды.  В за-
        висимости от оператора в поле операндов может быть  один,  два
        или несколько операндов.
             Примечания являются последним элементом предложения. При-
        мечания всегда начинаются с символа ";" и заканчиваются CR (ВК).


             2.4. Псевдокоманды

             2.4.1. Псевдокоманды перемещения

             Отличительной особенностью  макроассемблера  М80 является
        создание им перемещаемых модулей. Перемещаемость модуля облег-
        чает его отладку и тестирование, позволяет компоновать пограм-
        му из нескольких модулей,  написанных на разных языках.  Кроме
        того,  программу можно разбивать на сенгменты и указать, какие
        сегменты должны размещаться только в ОЗУ (сегменты данных),  а
        какие  могут быть занесены в ПЗУ (сегменты содержащие програм-
        му).  Эти сегменты создаются с  помощью  псевдокоманд  DSEG  и
        CSEG. Псевдокоманда ASEG используется при создании неперемеща-
        емых (абсолютных) кодов.  Псевдокоманда COMMON  создает  общие
        области  данных  для  каждого поименованного в программе блока
        COMMON.
             Для каждого сегмента программы ASEG,  CSEG или DSEG заво-
        дится свой счетчик адреса, который приостанавливает отсчет при
        смене типа сегмента и возобновляет отсчет,  когда снова встре-
        чается соответствующий сегмент. Значение счетчика адреса в лю-
        бом  сегменте  можно  изменить  с  помощью  псевдокоманды  ORG
        (п.2.4.12). По умолчанию всегда действует пседокоманда ASEG.


             2.4.1.1. ASEG

             Формат псевдокоманды: ASEG

             ASEG устанавливает значение счетчика адреса на абсолютный
        сегмент в памяти.  Значение счетчика будет продолжением преды-
        дущего  ASEG  (по умолчанию 0),  если после ASEG не стоит ORG.
        Для ассемблера ASEG является псевдокомандой по умолчанию.


             2.4.1.2. COMMON

             Формат псевдокоманды: COMMON /имя блока/
 
             COMMON устанавливает  счетчик  адреса на адрес выбранного
        общего блока памяти.  Для совместимости с оператором COMMON  в
        ФОРТРАНЕ  этот адрес всегда указывает на начало области.  Если
        "имя блока" опущено или состоит из пробелов,  то  блок  COMMON
        считается пустым.


             2.4.1.3. CSEG

             Формат псевдокоманды: CSEG

             CSEG устанавливает значение счетчика адреса  на  смещение
        относительно начала сегмента памяти,  содержащего коды команд.
        Значение адреса  будет  соответствовать  значению  предыдущего
        CSEG (по умолчанию 0), если только после CSEG не стоит псевдо-
        команда ORG.


             2.4.1.4. DSEG

             Формат псевдокоманды: DSEG

             DSEG устанавливает  значение  счетчика сегмента адреса на
        относительный адрес сегмента памяти,  содержащего данные. Зна-
        чение  адреса будет соответствовать адресу последнего DSEG (по
        умолчанию 0), если не было псевдокоманды ORG.


             2.4.2. DB - определить байт

             Формат псевдокоманды:

             DB "выражение","выражение",...
                    или
             DB "строка" ["строка"...]

             Аргументами для  DB  могут быть выражения или строки.  DB
        запоминает значения выражений или символов в строках в  после-
        довательных  адресах  памяти,  начиная с адреса,  указанного в
        счетчике адреса.  Значение выражения должно помещаться в одном
        байте. Если старший байт результата 0 или 255, то сообщение об
        ошибке не выдается. В противном случае выдается ошибка A.
             В выражениях  не могут присутствовать строки,  содержащие
        более 2-х символов. Старший бит каждого байта, отведенного под
        соответствующий символ, равен нулю.

                Примеры:

                0000   41 42     DB 'AB'
                0002   42        DB 'AB' AND 0FFh
                0003   41 42 43  DB 'ABC'


             2.4.3. DC - определить символ

             Формат псевдокоманды:

             DC "строка"

             DC запоминает символы,  заданные в  "строке",  последова-
        тельно,  начиная с адреса, указанного в счетчике адреса. В от-
        личие от DB,  в байте,  содержащем последний символ строки, в
        старшем разряде стоит 1. Если строка пустая, то выдается сооб-
        щение об ошибке.



             2.4.4. DS - определить область

             Формат псевдокоманды:

             DS "выражение"

             DS резервирует область памяти. Значение выражения показы-
        вает,  сколько байтов должно быть зарезервировано.  Все имена,
        присутствующие в выражени,  должны быть определены  к  моменту
        вычисления  выражения  при  первом проходе макроассемблера. В
        противном случае  при первом проходе  появится  флаг V, а  при
        втором проходе - флаг U. Если втором проходе флаг U не появит-
        ся, то все равно в модуле может быть ошибка, т.к. DS обрабаты-
        вается при первом проходе.


             2.4.5. DW - определить слово

             Формат псевдокоманды:

             DW "выражение","выражение",...

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


             2.4.6. END

             Формат псевдокоманды:

             END "выражение"

             Оператор END указывает на конец программы.  Если присутс-
        твует "выражение",  то оно указывает на стартовый адрес  прог-
        раммы. Если "выражение" отсутствует, то линкеру стартовый адрес
        не передается.

             *) Примечание.
                Если ассемблерная программа является основной програм-
                мой при компоновке,  то в ней должен быть указан стар-
                товый адрес. В противном случае линкер выдаст  сообще-
                ние об ошибке "нет стартового адреса". Если же ассемб-
                лерная программа является подпрограммой  по отношению
                к программе, написанной, например на ФОРТРАНЕ, то стар-
                товый адрес можно не задавать, т.к. он будет задан  в
                основной программе.


             2.4.7. ENTRY/PUBLIC

             Формат псевдокоманды:

             ENTRY "имя","имя",...
                или
             PUBLIC "имя","имя",...

             ENTRY или  PUBLIC  объявляют все имена,  присутствующие в
        списке, как доступные извне. После этого, к таким именам можно
        обращаться из других программ. Все имена в списке ENTRY/PUBLIC
        должны быть определены, иначе будет сообщение об ошибке  U.
        Имена, объявленные ENTRY или PUBLIC, заносятся в список глобаль-
        ных имен и используются линкером при удовлетворении внешних
        ссылок.

     
             2.4.8. EQU

             Формат псевдокоманды:

             "имя" EQU "выражение"

             По команде EQU символическому имени присваивается  значе-
        ние выражения. Если "выражение" имеет EXTRN, то выдается сооб-
        щение об ошибке.


             2.4.9. EXT/EXTRN

             Формат псевдокоманды:

             EXT "имя","имя",...
                или
             EXTRN "имя","имя",...

             EXT или EXTRN объявляют указанные имена внешними (EXTRN),
        т.е. определенными в другой программе. Объявить имя внешним
        можно также поставив в конце имени два символа решетки "##".
        Если имя, указанное в списке, определено в данной программе,
        то будет выдано сообщение об ошибке M.


             2.4.10. INCLUDE

             Формат псевдокоманды:

             INCLUDE  имя файла

             Три псевдокоманды INCLUDE, $INCLUDE и MACLIB эквивалент-
        ны. Псевдокоманда INCLUDE позволяет включать в текст исходной
        программы программы, записанные в других файлах. "имя файла" -
        это  имя  файла,  содержащего включаемую программу.  Тип файла
        должен быть ASM.
             Файл, присутствующий в псевдокоманде INCLUDE, открывается
        и транслируется в текущую программу сразу же за псевдокомандой
        INCLUDE.
             При выводе листинга в каждой строке,  содержащей  элемент
        включенного  файла,  сразу  же  после кода команды стоит буква
        "C". Вложение псевдокоманд INCLUDE не допускается. Если файл,
        указанный в INCLUDE, не существует, то будет выдано сообщение
        об ошибке "V" и данная псевдокоманда игнорируется.


             2.4.11. NAME

             Формат псевдокоманды:

             NAME ('имя программы')

             NAME задает  имя программы.  Значащими в "имени" являются
        только первые шесть знаков.  Имя можно задавать  и  с  помощью
        псевдокоманды TITLE.  Если в программе отсутствует NAME и TIT-
        LE, то в качестве имени берется имя исходного файла.


             2.4.12. ORG - задать счетчик адреса

             Формат псевдокоманды:

             ORG "выражение"

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


             2.4.13. PAGE

             Формат псевдокоманды:

             PAGE "выражение"

             Пседокоманда PAGE  дает  указание ассемблеру начать новую
        страницу вывода листинга.  Если в  псевдокоманде  присутствует
        "выражение",  то оно задает число строк на странице. Это число
        должно быть в диапазоне от 1 до 255.  По умолчанию  это  число
        равно 63.


             2.4.14. ASET

             Формат псевдокоманды:

             "имя" ASET "выражение"

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


             2.4.15. TITLE

             Формат псевдокоманды:

             TITLE "текст"

             TITLE задает заголовок программы, который может печатать-
        ся в первой строке каждой страницы. В тексте программы  может
        быть  только одна псевдокоманда TITLE иначе быдет сообщение об
        ошибке Q.  Если не задана псевдокоманда NAME , то первые шесть
        символов заголовка зададут имя модуля. Если в программе нет ни
        NAME, ни TITLE, то имя модуля будет задано из имени исходного
        файла.


             2.4.16. SUBTTL

             Формат псевдокоманды:

             SUBTTL "текст"

             Эта псевдокоманда выводит заголовок после заголовка, вы-
        веденного псевдокомандой TITLE.  Длина "текста" не должна пре-
        вышать 60 знаков.  В программе  может  быть  любое  количество
        SUBTTL.


             2.4.17.  .COMMENT

             Формат псевдокоманды:
     
             .COMMENT "разделитель" "текст" "разделитель"

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


             2.4.18.  .PRINTX

             Формат псевдокоманды:

             .PRINTX "разделитель""текст""разделитель"

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

             *) Примечание.
                .PRINTX выводит листинг при каждом проходе ассемблера,
                поэтому, если листинг нужен только при одном какомлибо
                проходе, то следует использовать псевдокоманды IF1 или
                IF2.


             2.4.19.  .RADIX

             Формат псевдокоманды:

             .RADIX "выражение"

             По умолчанию система счисления всех констант  -  десятич-
        ная. Псевдокоманда .RADIX позволяет изменить основание системы
        счисления по умолчанию (от 2  до  16).  "Выражение"  в  .RADIX
        всегда  в десятичной системе счисления независимо от основания
        системы счисления, действующей в данный момент.


             2.4.20.  .REQUEST

             Формат псевдокоманды:

             .REQUEST "имя файла","имя файла",...

             Эта псевдокоманда передает запрос линкеру на поиск неу-
        довлетворенных внешних имен в файлах, указанных в списке.
        Имена файлов в списке не должны содержать типов файла и ссы-
        лок на диски. Линкер ведет поиск файла с заданным именем и
        с типом - REL на диске по умолчанию.


             2.4.21. Условные псевдокоманды

                Список условных псевдокоманд

           IF/IFT "выражение"    Истина, если "выражение" не равно 0
           IFE/IFF "выражение"   Истина, если "выражение" равно 0
           IF1                   Истина при первом проходе
           IF2                   Истина при втором проходе
           IFDEP "символ"        Истина, если "символ" определен или
                                 объявлен EXTERNAL
           IFDEF "символ"        Истина, если "символ" не определен и
                                 не объявлен EXTERNAL
           IFB "аргумент"        Истина, если "аргумент" есть пробел.
                                 аргумент должен быть в угловых скобках
           IFNB "аргумент"       Истина, если "аргумент" не пробел.
                                 Используется для проверки некоторых  
                                 параметров. Аргумент должен быть в 
                                 угловых скобках.
           IFIDN "аргумент1",    Истина, если строка "аргумент1" иден-
                 "аргумент2"     тична строке "аргумент2". Аргументы
                                 должны быть в угловых скобках.
           IFDIF "аргумент1",    Истина, если строка "аргумент1" отли-
                 "аргумент2"     чается от строки "аргумент2".

             Все условные псевдокоманды имеют формат:

             IF XXX [аргумент]
             .
             .
             [ELSE
             .
             .
             ]
             ENDIF

             Допускается вложение условных псевдокоманд,  т.е. псевдо-
        команда внутри псевдокоманды. Во избежание ошибок все аргумен-
        ты условных псевдокоманддолжны быть известны при первом прохо-
        де.  Для IF,  IFT, IFF и IFE выражения должны содержать только
        определенные символы и все выражения должны быть абсолютными.


             2.4.21.1.  ELSE

             Каждая псевдокоманда IF должна иметь соответствующую ей
        псевдокоманду ENDIF, заканчивающую условие.


             2.4.22.  Псевдокоманды, управляющие выводом листинга

             Выводом листинга в файл можно управлять  с помощью двух
        псевдокоманд:
                 .LIST и .XLIST

             Если листинг не выводится, то данные псевдокоманды игно-
        рируются.
             По умолчанию действует псевдокоманда .LIST,  инициирующая
        вывод листинга.  Если встречается псевдокоманда .XLIST, то вы-
        вод листинга прекращается,  пока не  встретится  псевдокоманда
        .LIST.

            Вывод условных блоков, имеющих значение ложь, употребляет-
        ся тремя псевдокомандами:
           .SFCOND      подавление вывода условных блоков, имеющих
                        значение "ложь";
           .LFCOND      восстановить вывод условных блоков, имеющих
                        значение "ложь";
           .TFCOND      управлять выводом условных блоков, имеющих
                        значение "ложь", в зависимости от опции /X.

             Вывод таблицы  перекрестных  управляется  псевдокомандами
        .CREF  и .XCREF.  Если кросс-средства не используются,  то эти
        псевдокоманды игнорируются. Условие по умолчанию - .CREF. Если
        встречается псевдокоманда .XCREF, то вывод перекрестных ссылок
        прекращается до тех пор, пока снова не встретится псевдокоман-
        да .CREF.
             Вывод расширений  MACRO/REPT/IRP/IRPC  управляется  тремя
        псевдокомандами:

           .LALL    выводит полный макротекст для всех расширений;
           .SALL    выводит только сгенерированные объектные коды;
           .XALL    выводит сгенерированные объектные коды и соот-
                    ветствующий им текст (условие по умолчанию).


             2.4.23.  Перемещение перед загрузкой

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

                Пример:

                0000                   .PHAZE
                0100   CD 0106   F00:  CALL BAZ
                0103   C3 0007         JMP Z00
                0106   C9        BAZ:  RET
                0007   C3 0005   Z00:  JMP 5

             Все метки  внутри блока .PHAZE получают абсолютные значе-
        ния в зависимости от значения счетчика адреса  .PHAZE.  Однако
        коды, загружаются в текущую область памяти (т.е. с 0000 в этом
        примере). Позже их можно переслать по адресу 100h и выполнить.


             2.5. Макрокоманды и блоки

             Макросредства ассемблера MACRO включают в себя три макро-
        команды повторения (REPT, IRP, IRPC) и операцию макроопределе-
        ния (MACRO).  Каждая макрокоманда должна заканчиваться псевдо-
        командой ENDM.


             2.5.1. Терминология

           Для описания макрокоманд используются следующие термины:
        1) "фор.пар." - формальный параметр 
           Все формальные парметры являются допустимыми символическими
           именами, которые появляются в теле макрорасширения;
        2) "список форм.пар." - список формальных параметров, разделен-
           ных запятыми;
        3) "список арг." - список аргументов, разделенных запятыми.
           Список аргументов всегда заключен в угловые скобки. Если
           в угловых скобках нет символа или между двумя запятыми нет
           символа, то это нулевой аргумент в списке. При вложении уг-
           ловых скобок (скобки в скобках) каждый внутренний уровень
           скобок удаляется при использовании соответствующего аргу-
           мента. Строка в кавычках является допустимым аргументом;
        4) "список пар." - список параметров, разделенных запятыми.


             2.5.2. Блок REPT-ENDM

             Формат макрокоманды:

             REPT "выражение"
             .
             .
             ENDM

             Вычисляется значение "выражения"  и  группа  предложений,
        заключенная  между  REPT и ENDM,  повторяется полученное число
        раз.  "выражение" не может содержать внешние и  неопределенные
        имена.

             Пример:

             X   ASET   0
                 REPT   10   ;генерирует DB 1 - DB 10
             X   ASET   X+1
                 DB     X
                 ENDM

     
             2.5.3. Блок IRP-ENDM 

             Формат макрокоманды:

             IRP "фор.пар.",<список арг.>
             .
             .
             ENDM 
    
             Число аргументов  в списке определяет,  сколько раз будет
        повторена группа предложений,  заключенная между IRP  и  ENDM.
        При  каждом  повторении вместо всех вложений формального пара-
        метра подставляется очередное значение из  списка  аргументов.
        Если список аргументов пуст (<>), то группа предложений обра-
        батывается 1 раз и формальный параметр удаляется из всех вхож-
        дений.

             Пример:

             IRP   X, <1,2,3,4,5,6,7,8,9,10>
             DB    X
             ENDM

             Результат будет аналогичен предыдущему примеру.


             2.5.4. Блок IRPC-ENDM

             Формат макрокоманды:

             IRPC  "фор.пар.", строка (или "строка")
             .
             .
             ENDM

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

             Пример:

             IRPC   X, 0123456789
             DB     X+1
             ENDM

             Результат аналогичен двум предыдущим примерам.


             2.5.5.  MACRO

             Формат макрокоманды:

             "имя" MACRO "список форм.пар."
             .
             .
             ENDM

             С помощью  MACRO пользователь может создавать свои макро-
        команды и помещать их в различные участки программы.
             "имя" - это символическое имя, по которому впоследствии
        будут вызывать данную макрокоманду.
             "список форм.пар." - это список парметров, которые будут
        изменяться (замещаться фактическими  параметрами)  при  каждом
        вызове макрокоманды. Предложения между MACRO и ENDM составляют
        тело макрокоманды.
             Форма обращения к макрокоманде следующая:

             "имя" "список пар."

        где  "имя" - это имя присвоенное MACRO в макроопределении;
             "список пар." - это список фактических параметров, которые
             при вызове макрокоманды заменят соответствующие формальные
             параметры.
             Если число  фактических  параметров  превышает количество
        формальных параметров, то лишние фактические параметры игнори-
        руются. Если же число параметров меньше числа формальных пара-
        метров,  то вместо недостающих  фактических  параметров  будут
        подставлены нули.

             Пример:

             F00  MACRO  X
             Y    ASET   0
                  REPT   X
             Y    ASET   Y+1
                  DB     Y  
                  ENDM
                  ENDM

             При обращении  F00  10 эта макрокоманда сгенерирует те же
        предложения, что и в предыдущих примерах.


             2.5.6. EXITM

             Псевдокоманда EXITM  используется  для  завершения
        REPT/IRP/IRPC или вызова MACRO. При выполнении EXITM макрорас-
        ширение немедленно выводится,  а все оставшееся расширение или
        повторение не генерируется.  Если блок, содержащий EXITM, вхо-
        дит в другой блок, то внешний уровень продолжает расширяться.


             2.5.7. LOCAL

             Формат команды:

             LOCAL "список фор.пар."

             Эта псевдокоманда допустима только внутри  макроопределе-
        ния  MACRO.  При выполнении LOCAL ассемблер создает уникальное
        символическое имя для каждого формального параметра из  списка
        и подставляет потом это символическое имя при каждом вхождении
        данного формального параметра в макрорасширение.  Обычно,  эти
        уникальные  символические имена используются для задания меток
        внутри MACRO.  Это исключает возможность появления многократно
        определенных  меток  при неоднократных вызовах данной макроко-
        манды.  Символические имена, создаваемые при помощи LOCAL, на-
        ходятся в диапазоне от ..0001 до ..FFFF.  Поэтому пользователю
        в своих программах следует избегать имен типа ..NNNN.  Если  в
        макрокоманде есть LOCAL , то LOCAL должна быть в первом прело-
        жении макроопределения.


             2.5.8. Специальные макрооператоры и формы

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

             Пример:

             ERG    MACRO   X
             ERROR&X: PUSH  BC
                      LD    B,'&X'
                      JP    ERROR
                      ENDM
  

             В этом  примере  вызов ERG A создаст следующую последова-
        тельность предложений:

             ERROR&A: PUSH  BC
                      LD    B,'A'
                      JP    ERROR

             *) Примечание.
                Два символических  имени  считаются одинаковыми, если
        одно имя отличается от другого только наличием амперсанда. Так
        символическое имя ERRORA эквивалентно имени ERROR&A.

             ;;    Если в макрокоманде перед комментариями стоят две
                   точки с запятой, то эти коментарии не появляются в
                   макрорасширениях даже, если есть указание .LALL;

             $     ссылка на текущее значение счетчика адреса;

             !     символ, стоящий после восклицательного знака вводит-
                   ся литерально;

             NUL   это оператор, возвращающий значение "истина", если
                   его аргумент есть нуль. Остаток строки после NUL
                   рассматривается как аргумент для NUL. Условие IF NUL
                   аргумент будет "ложным", если при расширении первый
                   символ аргумента будет отличен от точки с запятой
                   или "CR" (ВК). Этот оператор рекомендуется исполь-
                   зовать для проверки наличия нулевых параметров в
                   условных псевдокомандах IFB и IFNB;

             %     этот оператор может использоваться только в аргумен-
                   те макрокоманды. % преобразует следующее за ним вы-
                   ражение (обычно символическое имя) в число в текущей
                   системе счисления. Во время макрорасширения получен-
                   ное число подставляется в формальный параметр. Ис-
                   пользование % позволяет вызывать макрокоманду с чис-
                   лом (обычно макровызов - это вызов с текстом из ар-
                   гументов). Выражение, следующее за % должно удовлет-
                   ворять тем же требованиям, что и в псевдокоманде DS.

                Пример:
            Нормально LB, являющееся аргументом для MACLAB, должно бы-
        ло подставляться аргументом MACRO. % преобразует LB в число и
        вместо Y подставляется уже число. Без %  результат трансляции
        был бы 'ERROR LB'.

                MACLAB MACRO  Y
                ERR&Y: DB 'ERROR &Y',0
                       ENDM
                MACERR MACRO X
                LB     ASET 0
                       REPT X
                LB     ASET LB+1
                       MACLAB %LB
                       ENDM
                       ENDM

             После макровызова MACERR  3 получим:
   
                ERR1: DB 'ERROR 1',0
                ERR2: DB 'ERROR 2',0
                ERR3: DB 'ERROR 3',0


             TYPE   оператор TYPE возвращает байт, который описывает 
                    две характеристики аргумента: перемещаемость и яв-
                    ляется ли аргумент внешним (EXTRN) или нет. Аргу-
                    ментом для TYPE может быть любое выражение (стро-
                    ковое, числовое, логическое). Если выражение не
                    верно, то TYPE вернет ноль. Структура возвращаемого
                    байта следующая:
                      младшие два бита определяют перемещаемость аргу-
                      мента следующим образом:
                      0   абсолютный;
                      1   перемещаемый относительно кода;
                      2   перемещаемый относительно данных;
                      3   COMMON перемещаемый.

                    Старший бит (80h) - бит EXTRN. Когда выражение со-
                    держит внешний символ, то бит равен 1.
                    Бит определенности - (20h). Когда выражение опре-
                    делено, то этот бит равен 1. Если же выражение не
                    определено или содержит EXTRN, то этот бит равен 0.
                    TYPE обычно используют внутри макрокоманд, когда
                    необходимо проверить тип аргумента.


                3. Руководство по эксплуатации компилятора M80

             3.1. Обращение к компилятору. Входные и выходные данные 

             Исходными данными для компилятора является файл, содержа-
        щий  программу  написанную  на макроассемблере,  и имеющий тип
        ASM. В результате работы компилятор создает файл типа REL, со-
        держащий модуль в перемещаемой форме.  Кроме того,  по желанию
        пользователя может быть создан файл с листингом и файл  перек-
        рестных ссылок.
             Запуск макроассемблера осуществляется следующей командой:

                  M80 "командная строка"
     
             Формат командной строки:

             "имя 1", "имя 2" ="имя 3"

             где   "имя 1" - имя файла, в который будет записан переме-
                   щаемый модуль;
                   "имя 2" - устройство, на которое будет выводится
                   листинг. Таким устройством может быть консоль (CON:),
                   принтер (PRN:) или файл на диске;
                   "имя 3" - имя файла, содержащего исходный текст про-
                   граммы.

             Если "имя 1" и "имя 2" опущены,  то по умолчанию  берется
        имя файла исходного текста.  Тип файла в "имя 1" всегда REL, в
        "имя 2" (если задан файл) всегда PRN,  а в "имя 3" всегда ASM.
        Если перемещаемый модуль и листинг не нужны, то слева от знака
        равенства надо поставить запятую.

             Примеры:

        M80 =SOURSE.ASM       транслировать программу SOURSE.ASM и
                              поместить объектный код в файл SOURSE.REL

        M80 ,PRN:=TEST        транслировать программу TEST.ASM и вывес-
                              ти листинг на устройство PRN (принтер);

        M80 SMALL,CON:=TEST   транслировать программу TEST.ASM, объект-
                              ный файл записать в SMALL.REL, а листинг
                              вывести на консоль.



             3.2. Опции компиляции

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

             Опция                  Действие
             -----                  --------

              /L    создать файл с листингом 

              /O    печатать в листинге все адреса и т.п. в восьмерич-
                    ной системе счисления

              /H    печатать в листинге все адреса и т.п. в шестнадца-
                    тиричной системе счисления (действует по умолчанию)

              /X    подавить вывод листинга условий, значение которых
                    есть "ложь"

              /R    создать объектный файл (действует по умолчанию)

              /P    создать объектный файл (переполнение стека при
                    опции /R)

              /C    создать файл перекрестных ссылок

              /M    инициализация нулями псевдооператора(ов) "DS"

              /I    настроить ассемблер на мнемоники I8080

              /Z    настроить ассемблер на мнемоники Z80 (по-умолчанию)


               Пример:

              M80 =TEST/L/P   оттранслировать файл TEST.ASM. Объектный
                              файл вывести в TEST.REL, а листинг в файл
                              TEST.LST.


             3.3. Формат листинга

             На каждой странице листинга первые две строки содержат:

                [TITLE ТЕКСТ]      MACRO        PAGE  X [-Y]
                [SUBTITLE ТЕКСТ]

           где  TITLE ТЕКСТ - текст заданный псевдокомандой TITLE;
                X - основной номер страницы. Он увеличивается только
                при появлении из исходного файла символа подачи новой
                страницы. Когда печатается таблица символов X=S;
                Y - младший номер страницы. Он увеличивается при появ-
                лении псевдокоманды PAGE или при заполнении текущей 
                страницы;
                SUBTITLE ТЕКСТ- текст, заданный псевдокомандой SUBTITLE.
                После вывода этих двух строк выводится одна пустая 
                строка, а затем очередная строка программы. Строка
                программы имеет вид:

            [CRF#]   [ERROR]   LOC#M   !XX!XXXX! .....  исходный текст

             Если выводится  таблица  перекрестных  ссылок,  то первый
        элемент в строке - номер для таблицы,  после него стоит символ
        табуляции.
             ERROR - это флаг ошибки,  если в строке есть ошибка. Если
        в стороке нет ошибки,  то вместо ERROR стоит пробел. Если таб-
        лица перекрестных ссылок не создается,  то флаг ошибки стоит в
        первой колонке.
             LOG#M - значение счетчика адреса,  которое в  зависимости
        от опций /H или /O, представляет собой 16-ричное число, содер-
        жащее 4 цифры или 8-ричное число,  содержащее 6  цифр.  Символ
        после числа - это индикатор перемещаемости:

                '        перемещаемый относительно кода;
                "        перемещаемый относительно данных;
                !        COMMON перемещаемый;
             ПРОБЕЛ      абсолютный;
                *        внешний.

             Далее печатаются три пробела,  после которых идет код ко-
        манды и операндов (если они есть у данной команды). Если стро-
        ка  листинга появилась из файла,  включенного по псевдокоманде
        INCLUDE,  то после кодов идет буква "C".  Если строка содержит
        макрорасширение (MACRO, REPT, IRP, IRPT), то после кодов стоит
        знак "+". Остаток строки содержит исходный текст.
             В конце  листинга  выводится  таблица  символических имен
        (меток).  Сначала в алфавитном порядке печатаются  имена  всех
        макрокоманд,  после  этого  выводятся  все символические имена
        программы.  После каждого символического имени выводится  знак
        табуляции,  а  затем печатается значение символического имени.
        Если имя типа PUBLIC,  то после его значения печатается  буква
        I. Далее печатается один из следующих знаков:

                U       имя неопределено;
                C       имя блока COMMON;
                *       внешнее имя;
             ПРОБЕЛ     абсолютное имя;
                '       перемещаемый относительно кода;
                "       перемещаемый относительно данных;
                !       COMMON относительный.


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

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

                Флаг             Значение
                ----             --------
                 A      Ошибка в аргументе.
                        Неправильный формат аргумента псевдокоманды
                        или аргумент вне допустимых границ.

                 C      Ошибка условного вложения.
                        ELSE без IF; ENDIF без IF; два ELSE на один IF.

                 D      Двойное определение символического имени.
 
                 E      Ошибка при использовании EXTRN.
                        Недопустимое использование символического име-
                        ни, объявленного EXTRN.

                 M      Многократно определенное символическое имя.

                 N      Ошибка в числе.
                        Неверное задание числа (например 8Q)

                 O      Неверный код операции или ошибочный синтаксис
                        ENDM, LOCAL вне блока; ASET, EQU или MACRO без
                        имени; неверный синтаксис в коде команды; не-
                        верный синтаксис в выражении.

                 P      Ошибка фазы.
                        Значение метки или имени в EQU изменилось при
                        втором проходе.

                 Q      Вопрос.
                        Обычно означает, что строка окончена неверно.
                        Это предупреждение о возможной ошибке.

                 R      Перемещение.
                        Недопустимое использование перемещения в выра-
                        жении.
 
                 U      Символическое имя не определено.

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