<< Вернуться к содержанию





       НАУЧНО-ИССЛЕДОВАТЕЛЬСКАЯ И ПРОИЗВОДСТВЕННАЯ ЛАБОРАТОРИЯ
                       "ПРОГРАМНО ОСИГУРЯВАНЕ"
                                София
       -------------------------------------------------------







                           IBM-PC / ПЫЛДИН

                           КРОСС-АССЕМБЛЕР




                           U n i C R O S S

                              версия 3.6


                       РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ

                              редакция 3












                             София - 1992

Copyright (с) 1989-92 НИПЛ"Програмно осигуряване", София, Болгария

     UniDOS, UniBIOS, UniASM, UniCROSS, UniED, UniBASIC и UniPASCAL
являются регистрированными торговыми марками и наименованиями
НИПЛ"Програмно осигуряване".

     "Пылдин" является регистрированной торговой маркой и
наименованием Содружества "АБАКУС", Болгария.

     Настоящий документ, как и любая его часть, не может быть
скопирован, передан или включен в информационно-поисковые системы
каким либо способом без предварительного письменного согласия со
стороны НИПЛ"Програмно осигуряване".

     Все права на операционную систему UniDOS, базовую систему
ввода/вывода UniBIOS, текстовый редактор UniED, ассемблеры UniASM и
UniCROSS, интерпретатор UniBASIC, интерпретатор и компилятор
UniPASCAL, как и на любую часть указанных программных продуктов,
сохранены.  НИПЛ"Програмно осигуряване" не несет ответственности за
работоспособность программных продуктов в случаях их
нерегламентированной перезаписи или использования.


     Программный дизаин и реализация:  н.с.Иво Ненов, н.с.Орлин Шопов,
н.с.Георги Петров,

     Автор документа и общая редакция:  к.т.н. инж. Недялко Тодоров

     Предтипографическая подготовка: ................


     НИПЛ "Програмно осигуряване" благодарит каждого, кто вышлет свои
замечания, рекомендации и деловые предложения по адресу:

                     НИПЛ"Програмно осигуряване"
                     бульвар "Ленин" - 125, блок 1
                     Болгария 1113 София,

               телефон: (..3592) 706248, 706158, 706317
                        телефакс: (..3592) 706248



                              СОДЕРЖАНИЕ

    1.  ВВЕДЕНИЕ

    2. СИНТАКСИЧЕСКИЕ КАТЕГОРИИ АССЕМБЛЕРА
    2.1. Символы
    2.2. Константы
    2.3. Выражения
    2.4. Списки

    3.  ТИП ПРОГРАММНЫХ СЕКЦИЙ И ВЕЛИЧИН
    3.1.  Тип программной секции
    3.2.  Тип символа
    3.3.  Тип выражения

    4. УСЛОВНАЯ КОМПИЛЯЦИЯ

    5. ФАЙЛЫ UniCROSS
    5.1. Входной (исходный - source) файл
    5.1.1.  Поле метки
    5.1.2.  Поле операции
    5.1.3.  Поле операнда
    5.1.4.  Поле комментария
    5.2. Отчетный (listing) файл
    5.3. Диагностический (error's) файл
    5.4. Объектный (object) файл
    5.5. PGM-файл

    6. ВЫЗОВ КРОСС-АССЕМБЛЕРА

    7. АДРЕСАЦИЯ МИКРОПРОЦЕССОРА СМ 601

    8. ДИРЕКТИВЫ КРОСС-АССЕМБЛЕРА
    8.1. Директивы определения символов
    8.1.1. EQU - присвоение значения
    8.1.2.  GLOBAL - определение глобального символа
    8.1.3. EXTERN - определение внешних символов
    8.1.4. PUBLIC - определение внутренных символов
    8.2. Директивы определения данных
    8.2.1. DB - определение байтов
    8.2.2. DW - определение слов
    8.2.3. DS - определение одинаковых байтов
    8.2.4. CHKSUM - контрольная сумма
    8.3. Директивы управления трансляцией
    8.3.1. SECTION - начало фиктивной секции
    8.3.2. ENDS - конец фиктивной секции
    8.3.3. PROC - начало процедуры
    8.3.4. ENDP - конец процедуры
    8.3.5. END - конец программы
    8.3.6. ORG - присвоение значения счетчику адреса
    8.3.7. ERROR - возбуждение состояния ОШИБКА
    8.3.8. RADIX - изменение счетной системы
    8.3.9. INCLUDE - вставка файла
    8.4. Директивы управления листингом
    8.4.1. LIST - включение/отключение листинга
    8.4.2. TRUNC - прерывание листинга

    Приложение A - КОМАНДЫ МИКРОПРОЦЕССОРА СМ 601
    Приложение B - ДИАГНОСТИЧЕСКИЕ СООБЩЕНИЯ
    Приложение C - РЕДАКТОР СВЯЗЕЙ ULINK




                             1.  ВВЕДЕНИЕ

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

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

     Настоящий документ является руководством пользователя
кросс-транслятора UniCROSS языка ассемблера микропроцессора СМ601
(аналог микропроцессора MC6800). UniCROSS предназначен для работы в
среде операционной системы MS DOS микрокомпьютеров фамилии IBM-PC и
позволяет создавать программы, выполняемые в среде операционной
системы UniDOS микрокомпьютеров фамилии "Пылдин".

     В настоящем документе термином "ассемблер" обозначается
как правило программный продукт UniCROSS. Процесс работы программного
продукта называется "трансляцией" или "ассемблированием". В
зависимости от контекста под термином "символ" следует подразумевать
или "графический (отображаемый) символ" или "символ языка ассемблера".

     Настоящий документ написан исходя из предположения, что читатель
уже владеет программированием на ассемблере микропроцессора СМ601, а
также усвоил основные понятия и приемы работы с операционными
системами MS DOS (PC DOS) и UniDOS.  Руководство не является учебником
языка ассемблера.

     При создании следующих версии транслятора изменения и дополнения
к настоящему руководству будут записаны в файле READ_ME.CRS, который
будет поставляться в составе дистрибутивного материала.

     Полную информацию о компьютере "Пылдин" и его операционной
системе можно найти в документах "UniDOS - Руководство пользователя" и
"UniBIOS - Руководство пользователя".

     В описании UniCROSS приняты следующие обозначения:

     <.....> - обязательная составляющая - вводится конкретное
значение описанного.  Например, <имя_файла> означает, что на указанном
месте следует ввести имя файла;

     [.....] - необязательная составляющая.

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



                2. СИНТАКСИЧЕСКИЕ КАТЕГОРИИ АССЕМБЛЕРА

                2.1. Символы

        Символом называется в ассемблере определенное в программе имя,
которому присвоено шестнадцатеричное число без знака в качестве
значения. Символ определяется директивой присвоения значения или
обявлением меткой.

        Имена составляются из букв латынского алфавита, цифр и
символов подчеркнутого пробела "_". Строчные и прописные буквы имеют
одинаковый смысл. Например, для ассемблера имена LooP, LOOP и loop
означают один и тот же символ. Длина имен ограничена только
программной строкой, но учитываются ТОЛЬКО ПЕРВЫЕ 16 символов.

      В зависимости от границ применимости в рамках одной программы
символы делятся на ГЛОБАЛЬНЫЕ и ЛОКАЛЬНЫЕ.

      ГЛОБАЛЬНЫЕ символы применимы (определены) в полной программе.

      ЛОКАЛЬНЫЕ символы применимы только в рамках процедуры, где они
определены. Эта особенность позволяет одному имени присваивать разные
значения в отдельных процедурах.

      С учетом последующей обработки объектного модуля редактором
связей часть символов (меток) при помощи соответствующих директив (см
далее EXTERN и PUBLIC) могут быть обявлены ВНЕШНИМИ или ВНУТРЕННЫМИ.

      ВНЕШНИМИ являются символы, определенные в другом, не текущем
модуле. Значения внешних символов не известны во время трансляции
модуля. Внешние символы применимы только там, где разрешено
использование неопределенных символов. Нельзя применять внешние
символы в инструкциях с относительной адресацией.

      ВНУТРЕННЫМИ называются символы, определенные в текущем модуле и
предназначенные для применения в других модулях. Нет ограничении в
применении внутренных символов в рамках модуля, где они определены.



                  2.2. Константы

       Константы в ассемблере имеют 8- или 16-битовое внутренное
представление и занимают один или два последовательные байта памяти.

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

     - десятичное число
       Пример: 123  234  456

     - шестнадцатеричное число - идентифицируется символом "$"
       Пример: $AB  $12  $F2

     - двоичное число - идентифицируется символом "%"
       Пример: %11  %01  %0001

     - графический символ - заключается в апострофы и
       константе присваивается значение, равное ASCII-коду символа.
       Символ апострофа в качестве графической константы удваивается.
       Пример: 'ш'  '§' 'А' ''''



             2.3. Выражения

       ВЫРАЖЕНИЕМ называется последовательность символов и/или
констант и/или символа "*" (обозначающий текущее значение счетчика
адресов), связанных опеарациями.

       Значение выражения имеет 16-битовое внутренное представление в
двух последовательных байтах памяти.

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

Приоритет 1
     - скобки "(" и ")";

Приоритет 2
     - логическое отрицание  (!)
     - смена знака  (-)

Приоритет 3
     - умножение (*)
     - деление (/)
     - получение остатка деления (%)
     - логическое И (AND) (&)
     - включающее логическое ИЛИ (OR) (|)
     - исключающее логическое ИЛИ (XOR) (||)

Приоритет 4
     - сложение (+)
     - вычитание (-)

     Операции одного приоритета выполняются в порядке следования.

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

     Если предусмотрено получить в результате работы UniCROSS
объектный модуль (OBJ) или перемещаемая выполнимая программа (PGM), в
выражениях НЕЛЬЗЯ ПРИМЕНЯТЬ ВНЕШНИЕ МЕТКИ (EXTERN). Допустимо ТОЛЬКО
сложение метки с константой и вычитание метки из метки. Во втором
случае в качестве результата получается константа.



              2.4. Списки

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






                  3.  ТИП ПРОГРАММНЫХ СЕКЦИЙ И ВЕЛИЧИН


     В языке ассемблера символы, константы и выражения называются
величинами. Величины характеризуются не только значением, но и типом:
относительным или абсолютным. Таким типом облагает и любая программная
секция.

     Абсолютными являются величины, представляющие собой фиксированные
адреса памяти или числа.  Поэтому константы всегда относятся к
величинам абсолютного типа.

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




                     3.1.  Тип программной секции

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

     Формирование секции осуществляется описанными ниже директивами
ORG и SECTION.  Тип секции соответствует типу выражения, примененного
при ее формировании.

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

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




                          3.2.  Тип символа

     Тип символов определяется по следующим правилам:

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

     2.  Метки и символ "*" счетчика адреса обладают типом текущей
программной секции.

     3.  Внешние и внутренные символы всегда относительного типа.





                         3.3.  Тип выражения

     Тип выражения определяется типом операции и ее операндов по
следующим правилам:

    ----------------------------------------------------------------
     тип операнда 1    операция    тип операнда 2  тип результата
    ----------------------------------------------------------------
     Относительный        -        Относительный = Абсолютный;

     Относительный        -        Абсолютный    = Относительный;

     Абсолютный           -        Относительный = Ошибка;

     Относительный        +        Относительный = Ошибка;

     Относительный        +        Абсолютный    = Относительный;

     Абсолютный           +        Относительный = Относительный;

     Абсолютный        <любая>       Абсолютный    = Абсолютный.



     Все остальные, кроме указанных в таблице, выражения недопустимы
и их результатом является ОШИБКА.



                        4. УСЛОВНАЯ КОМПИЛЯЦИЯ

      В ряде случаев очень полезно иметь возможность указать
компилятору что не нужно компилировать определенные части программы.
Простейшим примером такой ситуации является контрольная печать. Она
необходима только в процессе отладки программы. В таких случаях
говорим об "условной" (управляемой) компиляции.

      Условная компиляция управляется т.н. "идентификаторами"
компиляции. Фрагмент программы обрабатывается в зависимости от того
определен или не определен некоторый идентификатор.

      Идентификатор компиляции обявляется определенным при помощи
директивы .DEFINE. Ранее определенный идентификатор можно обявить
неопределенным при помощи директивы .UNDEF. Директивы имеют следующий
формат:

      .DEFINE <идентификатор>

      .UNDEF <идентификатор>

     Состояние идентификатора (определенное или неопределенное)
проверяется при помощи директив .IFDEF (интерпретация - ЕСЛИ
идентификатор ОПРЕДЕЛЕН) и .IFNDEF (интерпретация - ЕСЛИ идентификатор
НЕ ОПРЕДЕЛЕН). Далее обе указанные директивы обозначены IFxxxx и
программист выбирает какая из них отвечает его целям.

     Условная компиляция программных фрагментов осуществляется при
помощи следующей конструкции:

        .IFxxxx <идентификатор>
            <програмный_фрагмент_1>
       [.ELSE
            <програмный_фрагмент_2> ]
        .ENDIF

     Как видно из формального описания конструкции, применение части
.ELSE <програмный_фрагмент_2> не обязательно.

     Для UniCROSS указанная конструкция имеет следующее значение:

     ЕСЛИ    идентификатор определен/не определен
     ТО      ассемблировать фрагмент 1
     ИНАЧЕ   ассемблировать фрагмент 2


     ВНИМАНИЕ! Не забывайте вводить точку перед ключевым словом каждой
из директив условной компиляции: .DEFINE .UNDEF .IFDEF .IFNDEF .ELSE
.ENDIF.



                         5. ФАЙЛЫ UniCROSS

     UniCROSS работает с файлами четырех видов:

     - входной (source) файл, содержащий программу на языке ассемблера
в исходном виде;

     - отчетный (listing) файл, содержащий протокол процесса
трансляции;

     - диагностический (error's) файл, содержащий сообщения об
обнаруженных во время трансляции ошибках;

     - результативный (result) файл, содержащий объектный модуль
(object) или неперемещаемую выполнимую программу (command), или
перемещаемую выполнимою программу (program).

     Имена всех файлов UniCROSS составляются по общим правилам
операционной системы UniDOS.

     Конкретный тип результатичного файла определяется расширением
имени файла при соблюдении следующих требовании:

     - если в исходном программном тексте содержится директива ORG, то
генерируется неперемещаемая выполнимая программа (CMD);

     - если в исходном программном тексте содержится директива EXTERN,
то генерируется объектный модуль (OBJ);

     Объектные модули обрабатываются редактором связей ULINK. В
результате обработки получаются перемещаемые выполнимые программы
(program).

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

     source:       ASM
     listing:      LST
     error's:      ERR
     result:
      - object:    OBJ
      - command:   CMD
      - program:   PGM



     5.1. Входной (исходный - source) файл

     Входной (исходный) файл содержит программу на языке
ассемблера в исходном виде.

     Программа на языке ассемблера обрабатывается построчно.  Длина
строки должна быть не более 255 символов.  В одной строке должна быть
записана только одна инструкция. Пустая строка и строка, в которой
первым является символ ";", считаются строками комментария и не
обрабатываются UniCROSS.

     Каждая программная строка состоит из 4 полей:

             [ [метка] <операция> {операнд} ] [комментарий]

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

     При синтаксическом анализе строчные и прописные буквы не
различимы, кроме случая строки символов в качестве параметра.


                           5.1.1.  Поле метки

     Если первым символом строки не является пробел, табуляция или
";", то первое поле каждой строки - поле метки.  Поле метки не
обязательное.  Допускается ввод строки, содержащей только поле метки.

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

     В UniCROSS значение счетчика адреса отмечается символом звездочки
"*".

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



                         5.1.2.  Поле операции

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

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

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

     Все директивы описаны ниже, а мнемонические обозначения всех
машинных команд процессора СМ 601 даны в приложении А.

     В поле операции может быть записана команда INT вызова
определенной специальной функции операционной системы UniDOS INT $xx
(xx - шестнадцатеричное число номера функции).

     Все функции INT $xx описаны в документе "UniBIOS - Руководство
пользователя".




                         5.1.3.  Поле операнда

     Содержание поля операнда определяется операцией.  Операнд
указывает объект действия команды.

     Если команда двухоперандная, первый операнд записывается как
часть мнемоники команды.  Например, для команды ADD можно записать
ADDA или ADDB в зависимости от того, над каким регистром выполняется
операция.

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

     Напомним еще раз, что в UniCROSS принято обозначать счетчик
адресов символом звездочки "*".




                        5.1.4.  Поле комментария

     Первым символом поля комментария является символ ";".  В поле
комментария можно записать любые символы.  Они не влияют на ход
трасляции и на генерируемый объектный код.

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



                    5.2. Отчетный (listing) файл

     UniCROSS генерирует отчет (листинг) трансляции со следующим
форматом:

        <номер_строки> <адрес> <машинный_код> <исходный_текст>

     Например:

     -  адрес   код          метка   инстр.  операнд
     --------------------------------------------------------

     1  0000                         org     $100
     2  0100    CE 01 05             ldx     #message
     3  0103    3F 23                int     $23
     4  0105
     5  0105    48 65 6C 6C  message db      'Hello worls!',0
     6  0113                         end



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


                    5.3. Диагностический (error's) файл

     Во время своей работы UniCROSS выводит ДИАГНОСТИЧЕСКИЕ СООБЩЕНИЯ
об обнаруженных ошибках:

     - экран монитора в скользящем режиме;

     - в отчетный файл (listing), если предусмотрена его генерация;

     - в диагностический файл.

     Строка диагностического файла имеет следующий формат:

      <имя_исходного_файла> (<номер_строки>): ERROR: <сообщение>

     Диагностические сообщения приведены в приложении B.



                   5.4. Объектный (object) файл

     Объектный (object) файл имеет следующую структуру:

адрес             содержание
----------------------------------------------------------------
$00 (W) $5AA5;
$02 (W) $0001 (номер версии);
$04 (W) число внутренных (ENT) символов;
$06 (W) число внешних (EXT) символов;
$08 (W) длина сегмента кода;
$0A (L) сдвиг кода с начала файла;
$0E (W) сдвиг точки входа с начала файла - $FFFF означает, что нет
        точки входа;
$10 (W) длина сегмента данных;
$12-$1F 0
$20     - массив внутренных символов;
        - массив внешних символов;
        - код;
    (W) число сдвигов в массиве сдвигов;
        - массив сдвигов;

    (B) 0.


     Каждый элемент массива внутренных символов имеет следующий
формат:

$00-$0F - имя (в ASCIIZ - закончивает на  0);
$10 (W) - значение;
$12 (W) - тип: >= 0 - относительный;
               < 0  - абсолютный.



     Каждый элемент массива внешних символов имеет следующий формат:

$00-$0F - имя (в ASCIIZ - закончивает на 0);
$10 (L) - 0.




     Каждый элемент массива сдвигов имеет следующий формат:

$00 (B) тип: < 0 - внешний;
             >= 0 - не внешний;
                    бит 0 = LSB;
                    бит 1 = MSB;
                    Если оба бита = 1 - WORD;
$01 (W) - значение - если не внешний символ;
        - индекс в массиве внешних символов - если внешний символ;
$03 (W) - сдвиг относительно начала кода.  Если сдвиг больше длины
          кода, считается что это элемент сегмента данных.

     Элементы массива должны быть расположены в возрастающем порядке
сдвигов.



                      5.5. PGM-файл

      PGM-файл, содержащий перемещаемую выполнимую программу, имеет
формат:

адрес   содержание
----------------------------------------------------------
$00 (W) $A55A;
$02 (W) число слов в таблице сдвигов
$04 (W) сдвиг кода с начала файла
$06 (W) длина кода
$08 (W) сдвиг точки входа с начала файла
$0А (W) длина данных
$0C-$0F 0
$10     начало таблицы сдвигов относительно начала кода
        байтов релокации




                      6. ВЫЗОВ КРОСС-АССЕМБЛЕРА

     Кросс-ассемблер может быть вызван двумя командами операционной
системы MS DOS.

     Первая из них имеет вид:

              UNICROSS <source> [ <listing> [ <result> ]]

где: <source> - имя вводного (исходного) файла. Если расширение
                имени не указано, то по умолчанию принимается
                расширение .ASM;
    <listing> - имя файла листинга трансляции. Если расширение
                имени не указано, то по умолчанию принимается
                расширение .LST;
     <object> - имя выходного файла. Если расширение не указано,
                то по умолчанию принимается .PGM.

     Необязательные параметры <listing> и <object> можно заменить
символом ";".  В таком случае файл листинга не генерируется, а файл
результата будет иметь имя, одинаковое с именем исходного файла и
соответствующее расширение.

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

                               unicross

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

     Source filename [.ASM]:
     Listing filename [.LST]:
     Object filename [.PGM]:

     Если после ввода имени исходного файла будет введен символ ";",
диалог прекратится и остальные параметры будут определены уже
известным образом.




                 7. АДРЕСАЦИЯ МИКРОПРОЦЕССОРА СМ 601

     Микропроцессор СМ 601 допускает 7 видов адресации, представленных
в следующей таблице:

          Наименование                 Синтаксис операнда    Длина
         ----------------------------------------------------------

         Внутренная        Inherent                           1
         Аккумуляторная    Accumulator                        1
         Непосредственная  Immediate     #выражение          2(3)
         Прямая            Direct        выражение            2
         Расширенная       Extended      выражение            3
         Индексная         Indexed       выражение,Х          2
         Относительная     Relative      выражение            2


     Операции с ВНУТРЕННОЙ И АККУМУЛЯТОРНОЙ адресацией не
предусматривают операнды.  Примеры:

     asla
     clc
     comb
     decb

     Операции с НЕПОСРЕДСТВЕННОЙ адресацией имеют синтаксис:

                     <код_операции>  #<выражение>

                     <код_операции>  #/<выражение>

     Если инструкция не относится к 16-разрядным регистрам и:

     - в поле операнда введено #<выражение>, то учитывается младший
байт значения выражения;

     - в поле операнда введено #/<выражение>, то учитывается старший
байт значения выражения.

     Примеры:

     ldaa    #$FF
     adcb    #1
     ldx     #$FFFF
     adda    #/end_code - start_code


     Операции с ПРЯМОЙ адресацией имеют синтаксис:

                     <код_операции>  <выражение>

     Значение выражения должно быть в интервале [0, 255].  Прямая
адресация охватывает только нулевую страницу памяти - адреса в
интервале [$00, $FF].  Примеры:

     ldab    0
     stab    $20
     stx     $FE


     РАСШИРЕННАЯ адресация отличается от прямой только тем, что
значением выражения в поле операнда может быть любой доступный адрес
памяти компьютера.  Примеры:

     ldaa    $2000
     stx     $1FFE


     Операции с ИНДЕКСНОЙ адресацией имеют синтаксис:

                    <код_операции>  X,<выражение>

                    <код_операции>  <выражение>,Х

                    <код_операции>  X

     В третьем случае считается, что выражение имеет значение 0.

     Примеры:

     ldaa    X
     adda    X,1
     ldx     X,field1
     ldab    $33,X



     Операции с ОТНОСИТЕЛЬНОЙ адресацией имеют синтаксис:

                     <код_операции>  <выражение>

     К этой группе операции относятся операции условного и
безусловного перехода, исключая JSR и JMP.  В качестве операнда
принимается значение выражения за вычетом текущего значения счетчика
адреса.  Значение операнда должно быть в интервале [-129, +125].
Примеры:

     bra     exit
     bne     not_equ




                    8. ДИРЕКТИВЫ КРОСС-АССЕМБЛЕРА

                 8.1. Директивы определения символов

                   8.1.1. EQU - присвоение значения

     СИНТАКСИС:  <метка> EQU <выражение>
                 <метка>  =  <выражение>

     ПРЕДНАЗНАЧЕНИЕ:  присвоение метки тип и значение выражения.

     <метка> не должна быть уже определенной.  В <выражение> не должна
содержаться внешняя метка (обявленная директивой EXTERN).

     Пример:

     code_start   =   $100
     lo_byte      EQU hi_byte + 1



           8.1.2.  GLOBAL - определение глобального символа

     СИНТАКСИС:  GLOBAL <список_меток>

     ПРЕДНАЗНАЧЕНИЕ:  определение одной или более меток в качестве
глобальных.

     Директива GLOBAL должна следовать непосредственно за директивой
PROC.

     Пример:

print        PROC
             GLOBAL print_1, print_2
              .
              .
print_1      ldx     #message_1
              .
print_2      ldx     #message_2
              .
              .
             ENDP




             8.1.3. EXTERN - определение внешних символов

     СИНТАКСИС:  EXTERN <список_меток>

     ПРЕДНАЗНАЧЕНИЕ:  определение внешних для данного модуля меток.

     Если в программном модуле содержится директива EXTERN, то в
результате ассемблирования генерируется объектный модуль (OBJ).




           8.1.4. PUBLIC - определение внутренных символов

     СИНТАКСИС:  PUBLIC <список_меток>

     ПРЕДНАЗНАЧЕНИЕ:  объявление меток данного модуля, которые должны
быть доступными для других модулей программы.



                  8.2. Директивы определения данных


                    8.2.1. DB - определение байтов

     СИНТАКСИС:  DB <список_выражений>

     ПРЕДНАЗНАЧЕНИЕ:  запись в объектном коде одного или более байтов,
каждый из которых является значением очередного выражения списка.
Каждое выражение должно иметь значение в диапазоне 0..255.

     <выражение> может быть арифметическим выражением или строкой
символов, заключенных в апострофы.

     Пример:

num_base        DB      16
hex_chars       DB      '0123456789ABCDEF'
string          DB      'This is a string.', 13, 10, 0
hi_bytes        DB      first / 256, second / 256
lo_bytes        DB      first, second




                     8.2.2. DW - определение слов

     СИНТАКСИС:  DW <список_арифметических_выражений>

     ПРЕДНАЗНАЧЕНИЕ:  запись в объектном коде последовательности слов
(старший байт, младший байт), каждое из которых является значением
очередного выражения.

     Примеры:

words    DW      $C000, $D000, $E000, $F000
         DW      5*4096 + 3*16 +1
         DW      first_table, second_table, 0




              8.2.3. DS - определение одинаковых байтов

     СИНТАКСИС:  DS <выражение_1> [,<выражение_2>]

     ПРЕДНАЗНАЧЕНИЕ:  заполнение области памяти длиной в <выражение_1>
байтов символами, являющимися значениями <выражение_2>.

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

     Примеры:

buffer    DS      $200
          DS      $10, 32



                  8.2.4. CHKSUM - контрольная сумма

     СИНТАКСИС:  CHKSUM

     ПРЕДНАЗНАЧЕНИЕ:  формирование в неперемещаемой выполнимой
программе (.CMD) контрольного байта, переводящего контрольную сумму
файла в ноль.  Контрольная сумма считается однобайтовым сложением без
переноса.

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



                8.3. Директивы управления трансляцией

               8.3.1. SECTION - начало фиктивной секции

     СИНТАКСИС:  SECTION [выражение]

     ПРЕДНАЗНАЧЕНИЕ:  формирование фиктивной секции, начиная с адреса,
являющегося значением выражения или счетчика адресов, если выражение
не введено.

     Не допускается вложение фиктивных секций.  Конец фиктивной секции
формируется директивой ENDS.  Внутри фиктивной секции не генерируется
код. Выражение не должно содержать неопределенные и/или внешние
символы.




                 8.3.2. ENDS - конец фиктивной секции

     СИНТАКСИС:  ENDS

     ПРЕДНАЗНАЧЕНИЕ:  формирование конца фиктивной секции, начало
которой задано директивой SECTION.

     При выполнении директивы счетчику адреса присваивается значение,
которым обладал до выполнения директивы SECTION.  Применение директивы
вне фиктивной секции не имеет последствий.



                    8.3.3. PROC - начало процедуры

     СИНТАКСИС:  <метка> PROC

     ПРЕДНАЗНАЧЕНИЕ:  определение начала процедуры.  Конец
определяется директивой ENDP.

     Одна процедура может содержать в себе неограниченное число
других, вложенных процедур.

     Все метки в одной процедуре, не объявленные глобальными
директивой GLOBAL, считаются локальными.  Поиск некоторой метки
осуществляется сначала в текущей процедуре, а потом среди меток
"родительских" процедур.



                    8.3.4. ENDP - конец процедуры

     СИНТАКСИС:  ENDP

     ПРЕДНАЗНАЧЕНИЕ:  определение конца процедуры.  Начало
определяется директивой PROC.



                     8.3.5. END - конец программы

     СИНТАКСИС:  END [выражение]

     ПРЕДНАЗНАЧЕНИЕ:  формирование конца программы со стартовым
адресом, равняющимся значению выражения в случаях ассемблирования
перемещаемых модулей (.PGM и .OBJ).

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





          8.3.6.  ORG - присвоение значения счетчику адреса

     СИНТАКСИС:  ORG <выражение>

     ПРЕДНАЗНАЧЕНИЕ:  присвоение значения счетчику адреса.

     Выражение не должно включать метки и/или неопределенные и/или
внешние символы и результат его вычисления должен быть типа константы.
Не разрешается применение директивы внутри фиктивной секции.

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



             8.3.7. ERROR - возбуждение состояния ОШИБКА

     СИНТАКСИС:  ERROR <выражение>

     ПРЕДНАЗНАЧЕНИЕ:  возбуждение сосотояния "ОШИБКА" в случае, если
значение выражения отлично от нуля.

     Пример:

     ERROR   * % $100    ; ошибка, если текущее значение
                         ; счетчика адреса не равно границе
                         ; страницы памяти





               8.3.8. RADIX - изменение счетной системы

     СИНТАКСИС:  RADIX <выражение>

     ПРЕДНАЗНАЧЕНИЕ:  изменение текущей счетной системы на систему с
основанием, определенным значением выражения.  Допустимы значения
выражения в интервале 2..16.

     Пример:

     ldaa    #$3F
     RADIX   16
     ldaa    #3F



                    8.3.9. INCLUDE - вставка файла

     СИНТАКСИС:  INCLUDE <имя_файла>

     ПРЕДНАЗНАЧЕНИЕ:  вставка в транслируемый файл другого файла с
именем <имя_файла>.

     Параметр <имя_файла> должен задавать полное имя включаемого файла
с указанием устройства и/или директории, если они отличны от текущих.
Включаемый файл может содержать, в свою очередь, директиву INCLUDE.
Допускаются до 8 уровней вложения директивы.

     Пример:

     INCLUDE b:\dir_1\memory.inc




                 8.4. Директивы управления листингом


             8.4.1. LIST - включение/отключение листинга

     СИНТАКСИС:  LIST <ключ>

     ПРЕДНАЗНАЧЕНИЕ:  включение/отключение генерации файла листинга
кросс-ассемблирования.  Допускаются два значения ключа:  ON - включить
(по умолчанию); OFF - отключить.

     Пример:

     LIST ON
     .
     .
     LIST OFF



                  8.4.2. TRUNC - прерывание листинга

     СИНТАКСИС:  TRUNC <ключ>

     ПРЕДНАЗНАЧЕНИЕ:  включение/отключение прерывания генерации
листинга после первой строки зоны директив DB, DW и DS.  Допускаются
два значения ключа:  ON - включить (по умолчанию); OFF - отключить.

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





            Приложение A - КОМАНДЫ МИКРОПРОЦЕССОРА СМ 601

     Обозначения: А - accumulator A
                  B - accumulator B
                  M - Memory operand (8 bit)
                  M(16) - 16-bit memory operand
                  S - Stack pointer
                  X - Index register
                  P - processor status register

     Флаг состояния процессора: H - Half Carry
                                I - Interrupt disable
                                N - Negative
                                Z - Zero
                                V - Overflow
                                C - Carry
                                . - unchanged
                                * - changed
                                0 - cleared to 0
                                1 - set to 1


    ---------------------------------------------------------------
    LмнемоL    схема   L           вид адресации           LHINZVCL
    L код L  действия  L-----------------------------------L      L
    L     команды      L Inh LRel 2LImm 2LDir 2LInd 2LExt 3L      L
    ---------------------------------------------------------------
     ABA    A+B   -> A       1B  2                               *.****
      - Add B to A

     ADCA   A+M+C -> A                   89  2 99  3 A9  5 BD  4 *.****
      - Add Memory with Carry to A

     ADCB   B+M+C -> B                   C9  2 D9  3 E9  5 F9  4 *.****
      - Add Memory with Carry to B

     ADDA   A+M   -> A                   8B  2 9B  3 AB  5 BB  4 *.****
      - Add Memory to A

     ADDB   B+M   -> B                   CB  2 DB  3 EB  5 FB  4 *.****
      - Add Memory to B

     ANDA   A&M   -> A                   84  2 94  3 A4  5 B4  4 ..**0.
      - Logic AND Memory to A

     ANDB   B&M   -> B                   C4  2 D4  3 E4  5 F4  4 ..**0.
      - Logic AND Memory to B

     ASL    shift left                          68  7 78  6 ..****
      - Arithmetic Shift left M

     ASLA   shift left  48  2                               ..****
      - Arithmetic Shift left A

     ASLB   shift left  58  2                               ..****
      - Arithmetic Shift left B

     ASR    Aritm shr                           67  7 77  6 ..****
      - Arithmetic Shift right M

     ASRA   Aritm shr   47  2                               ..****
      - Arithmetic Shift right A

     ASRB   Aritm shr   57  2                               ..****
      - Arithmetic Shift right B

     BCC    if C = 0          24  4                         ......
      - Branch if no carry

     BCS    if C = 1          25  4                         ......
      - Branch if carry

     BEQ    if Z = 1          27  4                         ......
      - Branch if equal

     BGE    if N ^ V =0       2C  4                         ......
      - Branch if greater or equal

     BGT    Z|(N^V) = 0       2E  4                         ......
      - Branch if greater

     BHI    C | Z = 0         22  4                         ......
      - Branch if High

     BITA   A & M                   85  2 95  3 A5  5 B5  4 ..**0.
      - Bit test M with A

     BITB   B & M                   C5  2 D5  3 E5  5 F5  4 ..**0.
      - Bit test M with B

     BLE    Z|(N^V) = 1       2F  4                         ......
      - Branch if Less or Equal

     BLS    C | Z = 1         23  4                         ......
      - Branch if Low or Same

     BLT    N ^ V = 1         2D  4                         ......
      - Branch if Little

     BMI    N = 1             2B  4                         ......
      - Branch if Minus

     BNE    Z = 0             26  4                         ......
      - Branch if Not Equal
     BPL    N = 0             2A  4                         ......
      - Branch if Plus

     BRA    uncond            20  4                         ......
      - Branch Always

     BSR    Brnch Subrt       8D  8                         ......
      - Branch To SubRoutine

     BVC    V = 0             28  4                         ......
      - Branch if Overflow Clear

     BVS    V = 1             29  4                         ......
      - Branch if Overflow Set

     CBA    A - B       11  2                               ..****
      - Compare A with B

     CLC    0 -> C   0C  2                               .....0
      - Clear Carry

     CLI    0 -> I   0E  2                               .0....
      - Clear Interrupt mask

     CLR    0 -> M                           6F  7 7F  7 ..0100
      - Clear Memory

     CLRA   0 -> A   4F  2                               ..0100
      - Clear A

     CLRB   0 -> B   5F  2                               ..0100
      - Clear B

     CLV    0 -> V   0A  2                               ....0.
      - Clear oVerflow

     CMPA   A - M                   81  2 91  3 A1  5 B1  4 ..****
      - Compare A with M

     CMPB   B - M                   C1  2 D1  3 E1  5 F1  4 ..****
      - Compare B with M

     COM    not M -> M                               63  7 73  7 ..**01
      - Compliment (not) memory

     COMA   not A -> A       43  2                               ..**01
      - Compliment (not) A

     COMB   not B -> B       53  2                               ..**01
      - Compliment (not) B

     CPX    X - M(16)               8C* 3 9C  4 AC  6 BC  5 ..***.
      - Compare ind. reg. X with 16-bit Memory

     DAA    dec adjust  19  2                               ..****
      - Decimal adjust A

     DEC    M - 1 -> M                               6A  7 7A  6 ..***.
      - Decrement M

     DECA   A - 1 -> A       4A  2                               ..***.
      - Decrement A

     DECB   B - 1 -> B       5A  2                               ..***.
      - Decrement B

     DES    S - 1 -> S       34  4                               ......
      - Decrement Stack Pointer

     DEX    X - 1 -> X       09  4                               ...*..
      - Decrement Index Reg. X

     EORA   A ^ M -> A                   88  2 98  3 A8  5 B8  4 ..**0.
      - Excluding OR memory to A

     EORB   B ^ M -> B                   C8  2 D8  3 E8  5 F8  4 ..**0.
      - Excluding OR memory to B

     INC    M + 1 -> M                               6C  7 7C  6 ..***.
      - Increment Memory

     INCA   A + 1 -> A       4C  2                               ..***.
      - Increment A

     INCB   B + 1 -> B       5C  2                               ..***.
      - Increment B

     INS    S + 1 -> S       31  4                               ......
      - Increment Stack Pointer

     INX    X + 1 -> X       08  4                               ...*..
      - Increment Index reg. X

     JMP    jump                                6E  4 7E  3 ......

     JSR    jump Subrtn                         AD  8 BD  9 ......
      - Jump to SubRoutine

     LDAA   M -> A               86  2 96  3 A6  5 B6  4 ..**0.
      - Load A

     LDAB   M -> B               C6  2 D6  3 E6  5 F6  4 ..**0.
      - Load B

     LDS    M(16) -> S                   8E* 3 9E  4 AE  6 BE  5 ..**0.
      - Load Stack Pointer

     LDX    M(16) -> X                   CE* 3 DE  4 EE  6 FE  5 ..**0.
      - Load Index reg. X

     LSR    Logic shr                           64  7 74  6 ..0***
      - Logical Shift Right

     LSRA   Logic shr   44  2                               ..0***
      - Logical Shift Right A

     LSRB   Logic shr   54  2                               ..0***
      - Logical Shift Right B

     NEG    0 - M -> M                               60  7 70  6 ..****
      - Negate M

     NEGA   0 - A -> A       40  2                               ..****
      - Negate A

     NEGB   0 - B -> B       50  2                               ..****
      - Negate B

     NOP    NoOPeration 01  2                               ......

     ORAA   A | M -> A                   8A  2 9A  3 AA  5 BA  4 ..**0.
      - OR A

     ORAB   B | M -> B                   CA  2 DA  3 EA  5 FA  4 ..**0.
      - OR B

     PSHA   Push A      36  4                               ......
      - Push A

     PSHB   Push B      37  4                               ......
      - Push B

     PULA   Pull A      32  4                               ......
      - Pull A

     PULB   Pull B      33  4                               ......
      - Pull B

     ROL    rol C<-M<-C                   69  7 79  6 ..****
      - Rotate Left

     ROLA   rol C<-B<-C 49  2                                 ..****
      - Rotate Left A

     ROLB   rol C<-B<-C 59  2                                 ..****
      - Rotate Left B

     ROR    ror C->M->C                   66  7 76  6 ..****
      - Rotate Right

     RORA   ror C->A->C 46  2                                 ..****
      - Rotate Right A

     RORB   ror C->B->C 56  2                                 ..****
      - Rotate Right B

     RTI    Rtrn Intrpt 3B 10                               ******
      - Return from Interrupt

     RTS    Rtrn Subrtn 39  5                               ......
      - Return from SubRoutine

     SBA    A - B -> A       10  2                               ..****
      - Subtract B from A

     SBCA   A-M-C -> A                   82  2 92  3 A2  5 B2  4 ..****
      - Subtract with Carry from A

     SBCB   B-M-C -> B                   C2  2 D2  3 E2  5 F2  4 ..****
      - Subtract with Carry from B

     SEC    1 -> C                                       .....1
      - Set Carry flag

     SEI    1 -> I                                       .1....
      - Set Interrupt flag

     SEV    1 -> V                                       ....1.
      - Set Overflow flag

     STAA   A -> M                     97  4 A7  6 B7  5 ..**0.
      - Store A

     STAB   B -> M                     D7  4 E7  6 F7  5 ..**0.
      - Store B

     STS    S -> M(16)                         9F  5 AF  7 BF  6 ..**0.
      - Store Stack Pointer

     STX    X -> M(16)                         DF  5 EF  7 FF  6 ..**0.
      - Store index register X
     SUBA   A - M -> A                   80  2 90  3 A0  5 B0  4 ..****
      - Subtract from A

     SUBB   B - M -> B                   C0  2 D0  3 E0  5 F0  4 ..****
      - Subtract from B

     SWI    Soft Intrpt 3F 12                               .1....
      - Software Interrupt

     TAB    A -> B   16  2                               ..**0.
      - Transfer A to B

     TAP    A -> P   06  2                               ******
      - Transfer A to Processor status

     TBA    B -> A   17  2                               ..**0.
      - Transfer B to A

     TPA    P -> A   07  2                               ......
      - Transfer Processor status to A

     TST    M - 0                               6D  7 7D  6 ..**00
      - Test Memory

     TSTA   A - 0       4D  2                               ..**00
      - Test A

     TSTB   B - 0       5D  2                               ..**00
      - Test B

     TSX    S + 1 -> X       30  4                               ......
      - Transfer Stack pointer to X

     TXS    X - 1 -> S       35  4                               ......
      - Transfer X to Stack pointer

     WAI    Wait Intrpt 3E  9                               .1....
      - Wait for Interrupt





               Приложение B - ДИАГНОСТИЧЕСКИЕ СООБЩЕНИЯ


     Диагностические сообщения выдаются в следующем формате:

        <имя_файла>(<номер_строки>): ERROR: <текст_сообщения>

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


     Branch out of range.  - Переход вне модуля


     Can't open include file.  - Нельзя открыть файл для вложения.


     Can't open listing file.  - Нельзя открыть файл листинга.


     Can't open source file.  - Нельзя открыть исходный файл.  -
вероятнее всего не существует файл с указанным именем.


     Digit out of radix.  - Цифра вне текущей счетной системы.


     ENDS without SECTION.  - применение директивы ENDS без
директивы SECTION.


     Error writing object file.  - Ошибка во время записи
объектного файла - вероятнее всего нет свободного пространства на
диске.


     Expected close bracket.  - Отсутствует закрывающая скобка.


     Expected close quote.  - Отсутствует закрывающая кавычка
или апостроф.


     Expected constant expression.  - Не найдено обязательное
выражение типа константы.


     Expected expression.  - Не найдено обязательное для ввода
выражение.


     EXTERN not allowed in not relative mode.  - Директива
EXTERN запрещена в случаях неперемещаемого выходного файла.


     General syntax error.  - Общая синтаксическая ошибка -
вероятнее всего допущена ошибка при написании имени инструкции или
директивы.


     Illegal address mode.  - Неправильный тип адресации.


     Illegal character in text.  - В тексте найден не
разрешенный символ.


     Illegal expression.  - Неправильное арифметическое
выражение.


     Illegal name.  - Недопустимое имя - недопустимое сочетание
символов в поле метки.


     Illegal size of operand.  - Недопустимое значение операнда
- вероятнее всего значение операнда типа байт превышает 255.


     Improper use of CHECKSUM directive.  - Неправильное
применение директивы CHКSUM.  - директива CHKSUM применена второй раз
или применена в случае генерации перемещаемого выходного файла.


     Include file name expected.  - Не введено имя файла для
вложения.


     Include files too nested.  - Уровень вложения исходных
файлов больше допустимого (до 8 уровней).


     Integer overflow.  - Целочисленное переполнение (число
больше 65535).


     Missing ENDS.  - Отсутствует директива ENDS.


     ORG inside SECTION.  - применение директивы ORG внутри
фиктивной секции.


     ORG not allowed in relative mode.  - Не разрешено
применение директивы ORG в режиме генерации перемещаемого выходного
файла.


     Output buffer overflow.  - Переполнение буфера объектного
файла - длина объектного (выходного) файла не должна быть больше 32КВ.


     Proc nesting error.  - Неправильное вложение процедур.


     PUBLIC not allowed in not relative mode.  - Директива
PUBLIC запрещена в случаях неперемещаемого выходного файла.


     Redefinition of symbol <метка>.  - Переопределение метки
<метка>.


     There is no memory available.  - Нет больше доступной
(свободной) памяти.


     Undefined identifier <имя>.  - Неопределенный
идентификатор <имя>.


     Unexpected directive END.  - Неправильное применение
директивы END - вероятнее всего директива END применена во вложенном
файле.


     User error.  - Потребительская ошибка - сообщение
генерируется во время выполнения директивы ERROR, если значение
операнда отлично от нуля.




                 Приложение C - РЕДАКТОР СВЯЗЕЙ ULINK

     В составе операционной системы UniDOS микрокомпьютеров фамилии
"Пылдин" предлагается редактор связей ULINK, при помощи которого
раздельно ассемблированные объектные модули можно связать в выполнимую
программу.

     Вызов редактора связей осуществляется командой UniDOS-а:

                      ULINK [/[c][p]] <modules>

где:  c - опция формирования .CMD выходного файла, если это
          возможно.  Если опция пропущена, формируется .PGM файл;

      p - опция выравнивания объектных модулей на границе страницы;

      modules - список объектных модулей или библиотек, которые должны
          быть связаны в выполнимую программу.  Имена в списке
          указываются без расширений.  По умолчанию считается что
          мудули имеют расширение имен .OBJ, а библиотеки - .LIB.

     В результате работы редактора связей создается выполнимой файл
(программа) с именем, совпадающем с именем модуля, содержащего
директиву MAIN и с расширением имени PGM или CMD, в зависимости от
отсутствия или наличия опции "/c" (см.  выше).


     Каждый объектный модуль состоит из сегмента кода и сегмента
данных.  Сегмент данных следует непосредственно за сегментом кода и
может содержать ТОЛЬКО неинициализированные данные.  Для создания
такого сегмента следует применить директиву SECTION в начале сегмента
данных.

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

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

     Если генерируется CMD файл, программа должна сама проверить
существует ли пространство памяти, достаточное для размещения сегмента
данных.  В случае генерации PGM файла такое соответствие
гарантируется.

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

     Code too large - сводной сегмент кода длиннее 64Kбайт.

     Data too large - сводной сегмент данных длиннее 64Kбайт.

     Error in object table - ошибка в таблице сдвигов объектного
модуля.

     File too large - модуль длиннее 64Кбайт.

     Invalid entry point - неправильная точка входа - точка входа CMD
файла не находуится в его начале.

     Invalid file format - неправильный формат объектного модуля.

     No entry point given - не указана точка входа - директива MAIN не
введена.

     Out of memory - недостаточный объем свободной памяти.

     Read error - ошипка при чтении файла.

     Too many entry points - много входных точек - директива MAIN
встечается более одного раза.

     Too many object files - много объектных файлов - в списке указано
более 256 имен объектных файлов.

     Write error - ошибка записи файла.