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




>>>>>>> N.B.
Все что считается важным маркированно
так как это сделано здесь.

Поищите и прочитайте
как минимум эти секции.

Все что относиться к совместимости с as11
(бесплатной ассемблер фирмы Motorola)
можно найти если поищите as11.

Если указано что чтото сделано в целях совместимости
то это не означет совместимость с as11. Совместимость
с as11 только там где явно написана.
<<<<<<< N.B.

                              СОДЕРЖАНИЕ

    1.  ВВЕДЕНИЕ

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

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

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

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

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

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

    8. ДИРЕКТИВЫ КРОСС-АССЕМБЛЕРА
    8.1. Директивы определения символов
    8.1.1. EQU - присвоение значения
    8.2. Директивы определения данных
    8.2.1. определение байтов            - DB, LSB, MSB
    8.2.2. определение слов              - DW, DWP, DWN
    8.2.3. определение двойных слов      - DD, DDP, DDN
    8.2.4. определение одинаковых байтов - DS
    8.2.5. CHECKSUM - контрольная сумма
    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 - прерывание листинга
    8.5. Директивы для совместимости с as11
    8.6. Директива разрешающая использования константаь типа xxxB




                             1.  ВВЕДЕНИЕ

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

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

     Настоящий документ является руководством пользователя
кросс-транслятора языка ассемблера микропроцессора MC6800, MC68HC11
(можно изпользовать и для MC6802, MC6808). Транслятор предназначен
для работы в среде операционной системы MS DOS микрокомпьютеров
фамилии IBM-PC.

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

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

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

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

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

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



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

                2.1. Символы

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

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

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

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

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


                  2.2. Константы

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

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

     - десятичное число (можно закончит '.')
       Пример: 123  234  456  123456.

       Intel style decimal format: xxxxD не реализован так как ест опасность
       совершит ошибку. Например: забыть $ и написать только 123d тогда
       транслатор не предупредит вас а сгенерирует 123. Так как использование
       таких констант (десятичных окончивающих на D) практически не
       используется то он не реализован.

     - шестнадцатеричное число
         - C style:        начинается "0x"  пример: 0xAB  0x1234  0xF21234
         - Motorola style: начинается "$"   пример:  $AB   $1234   $F21234
         - Intel style:  заканчивается H    пример:  0ABh   1234H  0F21234h

     - двоичное число
         - Motorola Style: начинается "%"   пример:  %11  %01   %10001
         - pseudo C style: начинается "0i"  пример: 0i11  0i1  0i10001
         - pseudo Intel style: заканчивается I ...:   11I  1i    10001I
         - Intel style:  заканчивается B    пример:   11B  1b    10001b
           (этот формат потенциально опасен (например 1b такая же ошибка
            если не указали $ как и уже описанная ситуация при xxxxD),
            но так как этот формат используется то он реализован. За
            это нужно написать директиву .intelbin)

     - восмеричное число
         - Motorola Style: начинается "@"   пример:  @123   @232   @021
         - pseudo C style: начинается "0o"  пример: 0o123  0o232  0o021
         - pseudo C style: начинается "0Q"  пример: 0Q123  0q232  0Q021
         - Intel style: заканчивается o или Q  пр.:   123q  0232Q    21o
         ! C style не поддерживяается (т.е. 0123 не восмеричная константа)

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

>>>>>>> N.B.
        Во всех численных константах можно использоват символ '_'. Транслятор
пропускает его, но зато повышается читаемость.
        Сравните сами:   %11011101  =  %1101_1101
<<<<<<< N.B.



             2.3. Выражения

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

       Значение выражения вычисляется как 32 битовое число.

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

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

Приоритет 2
     ! - логическое отрицание (побитовое)
     ~ - логическое отрицание (побитовое) (еквивалентно !)
     - - смена знака (унарный минус)

Приоритет 3
     * - умножение
     / - деление
     % - получение остатка деления
     \ - получение остатка деления (для совместимости с более ранных версии)
     & - побитовое И

Приоритет 4
     + - сложение
     - - вычитание
     | - побитовое включающее ИЛИ
     ^ - побитовое исключающее ИЛИ

Приоритет 5
     все операции сравнения: <, >, <=, >=, =, <> (или !=)
     результат: false = 0, true = $ffff_ffff

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

     Для совместимости с предыдущей версии транслятора:
     Если начать выражение символом "/" то результат будет старшии байт
вычисленного выражения.
     Пример:    /(1+2*3+257) = 1, (1+2*3+257)/256 = 1


              2.4. Списки

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


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

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

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

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




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

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

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

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




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

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

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

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




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

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

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

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

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

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

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

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

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

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

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

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

>>>>>>> N.B.
        Идентификатор не больше 15 символов.
        Прописные и строчные буквы не различаются.
<<<<<<< N.B.

   Можно использовать и вычисляемое выражение
        .IF <выражение>
            <програмный_фрагмент_1>
       [.ELSE
            <програмный_фрагмент_2> ]
        .ENDIF



                         5. ФАЙЛЫ

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

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

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

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

     - результативный (result) файл

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

     source:       ASM
     listing:      LST
     error's:      ERR
     result:       BIN

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

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

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

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

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

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

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


                           5.1.1.  Поле метки

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

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

     Значение счетчика адреса отмечается символом звездочки "*".
Например: 123 + * - label

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



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

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

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

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

     Все директивы описаны ниже, а мнемонические обозначения всех
машинных команд процессора 68HC11 даны в MC68HC11.prn.

     В поле операции может быть записана команда INT. Тогда генерируется
код SWI и потом байт содержущии параметр инструкции.
Это для совместимости с предыдущих версиях транслятора.




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

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

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

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

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




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

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

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

Пустая строка и строка, в которой первым является символ "*" (позиция 1),
считаются строками комментария и не обрабатываются транслятора.


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

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

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

     Например:

 <адрес><машинный_код>  <номер> <исходный_текст>
   e0d3: ad 00              548                 jsr     x[0]
   e0d5: 24 03      (e0da)  549                 bcc     err_request
   e0d7: 86 06              550                 lda     #6              ; ack
   e0d9: 8c                 551                 db      _cpx_
   e0da:                    552 err_request
   e0da: 86 15              553                 lda     #21             ; nack
   e0dc: 7f 003b            554                 clr     rs232_ndx
   e0df: 7e f2fc            555                 jmp     send_rs_byte
   e0e2:                    556
   e0e2: fa4a               557 RequestTBL      dw      rq_test_mode    ; test_mode requests
   e0e4: f435               558                 dw      rq_get_param    ; get parameter value


>>>>>>> N.B.
   Трансляютор однопасов. Когда необходимо сгенерировать listing то только
тогда он делает второй пас. Это означает что если оборужена ошибка, то
listing файл вообще не будет сгенерирован. (Останется стары если был.)
<<<<<<< N.B.


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

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

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

     - в диагностический файл, если предусмотрена его генерация;.

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

     * Error <номер ошибки> at <имя_исходного_файла>(<номер_строки>), <сообщение>

     Если предусмотрена генерация диагностического файла и ошибки нет то
он стирается.

     Диагностические сообщения приведены в:
            MC68HC11.us



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

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

      usage: _68 [options] filename [options]
        /Dxxx   - define conditionals;
        /Ixxx   - paths for include files;
        /Bxxx   - path for .bin file;
        /E[xxx] - error messages filename (including path);
        /L[xxx] - listing filename (including path);
        /X[xxx] - print cross reference;
        /Q-     - quiet compilation off (termometer style)
        /Q+     - quiet compilation on (filenames and numbers)
        /Q*     - quiet compilation (filenames only)
        @xxx    - use config file xxx (including path).

filename - имя вводного (исходного текста) файла.
           Если расширение имени не указано,
           то по умолчанию принимается расширение .ASM;

/Dxxx    - задание симовла услоной компиляции
           например /dTEST еквивалентно директиве .define TEST

/Ixxx    - задает список путей куда будут искаться включаемые файлы

/Bxxx    - место куда нужно записать результатной файл

/E[xxx]  - запрос на получение диагностического файла (если xxx задано
           то это и будеть его имя)

/L[xxx]  - запрос на получение отчетного (listing) файла (если xxx задано
           то это и будеть его имя)

/X[xxx]  - запрос на получение cross-reference файла (если xxx задано
           то это и будеть его имя)

/Q-      - (non quiet compilation) графическое представление прогреса
/Q+      - (quiet compilation) печатются только имена файлов и номера строк
/Q*      - печатются только имена файлов

@xxx    -  имя файла в котором можно задать все параметры. По умолчанию
           он имеет имя MC68HC11.cfg.
           Транслятор ищет его в текущей директории а потом (если не
           нашел) там откуда его вызвали.
           В файл можно задавать те же самые параметры, но по один на
           строке.
           Это предусмотрено эсли вам нравиться какие нибудь специфические
           параметры. Например всегда хочеться диагностическии файл
           тогда поставте /e в файле MC68HC11.cfg (этот файл лучше всего
           расположить там где поставите и _68.exe).

        Если хотите можно использовать "output file redirection" и получит
описание действия транслятора в текстовой файл. Наример после выполнения
        _68 ext > xxx.txt
        То в xxx получиолось:
******* xxx.txt *******
MC68HC11 Assembler v5.11.          (c) 1992, 1998 YGP software          by YGP
    MC68HC11.inc  148 lines.
       build.inc    1 line.
        date.inc    1 line.
        sel5.asm   71 lines,    72($0048) bytes.
        free.asm  376 lines,   536($0218) bytes.
         r2r.asm   98 lines,   131($0083) bytes.
         r2p.asm  166 lines,   209($00d1) bytes.
         p2r.asm 1136 lines,  1628($065c) bytes.
        talk.asm  125 lines,   140($008c) bytes.
     spctalk.asm  106 lines,   130($0082) bytes.
      eeprom.asm   57 lines,     2($0002) bytes.
       rs232.asm  411 lines,   630($0276) bytes.
    messages.asm   71 lines,   464($01d0) bytes.
    testmode.asm  607 lines,   885($0375) bytes.
         ext.asm 2283 lines,  8192($2000) bytes.
5657 lines, 8192 bytes, 2.6 sec (2175.8 lps).
Code generated in file: ext.bin
******* end of file *******

<<<<<<< N.B.
                 7. АДРЕСАЦИЯ МИКРОПРОЦЕССОРА MC6800/MC68HC11

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

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

>>>>>>> N.B.
     Микропроцессор MC68HC11 допускает еще инструкции BCLR, BRCLR, BSET, BRSET
у них два или три операнда.

Синтаксис только для BCLR, BSET:
     BCLR op1 #op2       (тоже самое для BSET op1 #op2)
     здесь op1 - должен иметь адресацию: Direct или Indexed
           op2 - выражение (второй операнд должен иметь Immediate address mode)

Синтаксис только для BrCLR, BrSET:
     BrCLR op1 #op2, op3       (тоже самое для BrSET op1 #op2, op3)
     здесь op1 - должен иметь адресацию: Direct или Indexed
           op2 - выражение (второй операнд должен иметь Immediate address mode)
           op3 - должен имет Relative address mode (обычно это метка перехода)
     Обратите внимание на то что разделител между op2 и op3 являтся ','.

Для совместимости с бесплатно распространяемого асемблера as11
(фирмой Motorla) предусмотрена возможность что бы раделитель между op2 и op3
был только пробел. Для это исползуите директиву as11.

<<<<<<< N.B.

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

     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

>>>>>>> N.B.
     Можно использовать символ '<' перед операндом тогда это адресация
должна быть прямая (direct, zero page). Это означает что транслятор
отмет ошибку если операнд не находиться в интервале [0, 255].
<<<<<<< N.B.

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

     ldaa    $2000
     stx     $1FFE

     Можно использовать символ '>' перед операндом тогда это адресация
должна быть расширенная (extended). Это означает что транслятор что даже
если операнд в интервале [0, 255] то будет применена расширеная адресация.


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

     <код_операции>  X,<выражение>
     <код_операции>  <выражение>,Х
     <код_операции>  X
     <код_операции>  X+выражение
     <код_операции>  X.выражение
     <код_операции>  X[выражение]

     В третьем случае считается, что выражение имеет значение 0.
     Тот же самы синтаксис используется и для Y (MC68HC11).

     Примеры:

     ldaa    X
     adda    X,1
     ldx     X.field1
     ldab    x+$33
     ldab    x[i]

>>>>>>> N.B.
     Если выражение не в интервале [0, 255] то выдается предупреждение,
что бы оно не появлялось исползуйте & $ff (только тогда когда надо).
     Например:  ldaa x[n & $ff]
                ldab x, $ff & field1
<<<<<<< N.B.


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

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

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

Примеры:

not_equ
     bra     exit
     bne     not_equ
exit

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

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

  Пример:
        .if n < 23
          ....
        .else
          ....
        .endif


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

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

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

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

     <метка> не должна быть уже определенной.

        EQU и = еквивалентные
        == как и =, но метка определяется только в качестве локальной
          ето предусмотренно для использования в процедурах. Если
          использовать == вне процедуры то оно еквивалентно EQU

     Пример:

     code_start   =   $100
     lo_byte      EQU hi_byte + 1

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


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

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

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

     <список_выражений> = {[<повторитель>] <выражение> [<повторитель>] [,] }

     <выражение> может быть арифметическим выражением или строкой
символов, заключенных в апострофы. Перед или после этого выражения можно
поставит повторитель (в скобках []).

     Примеры:

num_base        DB      16
hex_chars       DB      '0123456789ABCDEF'
string          DB      'This is a string.', 13, 10, 0

zero_10         db      0 [10]  ; 0 в десят раз
one_23          db      [23] 1  ; 23 бата содержущие единицы


        LSB еквивалентно DB
        MSB генерирует только старшии байт (путем деления на 256)

     Пример:
hi_bytes        DB      first / 256, second / 256
lo_bytes        DB      first, second

hi_bytes        MSB     first, second
lo_bytes        LSB     first, second

      Для совместимости с as11
        FCC = FCB = DB


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

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

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

     Примеры:

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

    DWP еквивалентно DW
    DWN генерирует слова, но сперва младшии потом старшии байт

    DWP - Define Word Positive byte sex
    DWN - Define Word Negative byte sex

      Для совместимости с as11
        FDB = DW

                     8.2.3. определение двойного слова - DD, DDP, DDN

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

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

    DDP еквивалентно DD
    DDN генерирует слова, но сперва младшие потом старшие байты

    DDP - Define Double word Positive byte sex
    DDN - Define Double word Negative byte sex


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

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

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

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

     Примеры:

buffer    DS      $200
          DS      $10, 32

      Для совместимости с as11
        RMB = DS


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

     СИНТАКСИС:  CHECKSUM

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

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


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

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

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

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

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


Пример:
        section WorkArea
wrk_b   db      0       ; рабочая клетка (байт)
wrk_w   dw      0       ; рабочая клетка (слово)
wrk_b1  ds      1       ; рабочая клетка (байт)
wrk_w2  ds      2       ; рабочая клетка (слово)
        ; ошибка если выти за пределы рабочей области
        error   *-WorkArea > WorkAreaSize
        ends

>>>>>>> N.B.
Второй пример: Описана структура и процедура поиска в
               связаном списке структур. В процедуре я использовал
               мои любимые метки quit и loop, так как они локальные
               то их имена можно использовать и в других процедурах.
               Но ни в коем случае не используйте их как глобальные.
               Если это случится, то транслятор сочтет как ошибка все
               места где ети метки обявлены в локальных процедур. И так
               как я обычно употребляю огромное количество loop и quit
               то все они будут в списке ошибок (их дефиниция).

         section 0
next       dw      0
id_number  dw      0
data2      ds      123
         ends

**************************************************
* import: X reg points to beginning of linked list
*         D reg contains id_number to search
* export: X reg = 0 (if error) or
*         contains ptr (if ok)
*
SearchNum       proc
                cpx     #0
                beq     quit
loop
                cmpd    x.id_number
                beq     quit
                ldx     x.next
                bne     loop
quit            rts
SearchNum       endp
<<<<<<< N.B.


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

     СИНТАКСИС:  ENDS

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

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

     Пример: смотрите директива SECTION


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

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

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

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

     Все метки в одной процедуре если не описаны при помощи
директивы EQU (или =), считаются локальными.
Поиск некоторой метки осуществляется сначала в текущей процедуре,
а потом среди меток "родительских" процедур.

     !!! Не разрешается иметь метки с одиноковые имена в текущей и
родительских процедур. Пример:
****************

my_proc         proc
                ...
wait            decb                                          <-
                bne     wait                                     \
                ...                                               \
                                                                   \
second          proc                                                \
                ...                                                  \
                jmp     wait    ; куда мы хотим передать управление?  \
                ...                                                   /
                                                                     /
wait            lda     #0                                      <-- /
                ...                                                /
                                                                  /
second          endp                                             /
my_proc         endp                                            /
                                                               /
                ...                                           /
wait            ldab    #1                                  <-
                ...
*************

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


     Если в процедуру необходимо описать глобальную метку, то:
          1. Можно описать при помощи EQU. Пример:
                entry   =       *
          2. Можно поставить ':' в конце метки. Пример:
                        ....
                entry:  ldaa    x[0]
                        ...
     Если необходимо описать локольная константа (используя equ), то
используйте ==. Пример:

                procsize ==     ProcEnd-ProcBeg
                ProcBeg
                        ....
                ProcEnd

     Пример для использования PROC: смотрите директива SECTION

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

     СИНТАКСИС:  [метка] ENDP

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

     Если начало процедуры описано в include файл, то конец (endp)
должен находиться в тот файл.

     Пример: смотрите директива SECTION


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

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

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

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

     Директива только для совместимости с предыдущих версиях этого
транслятора (он использовался на 8 бытовых машин).



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

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

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

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


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

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

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

     Пример:

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


                    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 - отключить.

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

    8.5. Директивы для совместимости с as11

        Директивы ассемблера as11
            FCC, FCB еквивалентные DB
            FDB      еквивалентна  DW
            RMB      еквивалентна  DS

     директива as11

     синтаксис: as11 [ON или OFF]

     Предназначение: для совместимост инструкции BRCLR BRSET.
                     если ключ не задан предполагается ON

     Так как as11 использует для разделителя операндов пробелы то
        BSET    xx 12           ; только для as11
     можно написать и как
        BSET    xx #12          ; ето правильно и для as11 и для _68

     К сожелению
        BrSET   xx #12, label   ; правильно для _68
     не принимается as11. Поетому если необходимо можно задать директиву
        as11 on

     тогда транслятор _68 принимает как разделител и пробел. Но тогда
не можете использовать пробел во втором операнде. Пример
     brclr n #12 + 1, label  ; правильно если as11 off
     brclr n #12+1,   label  ; правильно всегда (as11 on или off)
     brclr n #12+1    label  ; правильно если as11 on

    8.6. Директива разрешающая использования константаь типа xxxB

        синтаксис: intelbin [on|off]

        Предназначение: Тому кто хочется использоват двоичние константы в
стиле intel, пример:  0101B.

        Проблема в том что если забыть '$' то все что оканчивается B и
содержит только 0 и 1 будет считатся правилно.

        Пример: ESC = 27 = $1b = %011_011 = 33q

                ldaa    #27
                cmpa    #1b     ; это вполне возможняя ошибка
                bne     differ  ; переход будет сделан так как 1 <> 27

    9. Дополнительные инструкции:

    Файл MC68HC11.PRN содержит таблица инструкции процесора MC6800 и MC68HC11
(те которые есть только в MC68HC11 помечены *). В правой колоне мнемоники
дано алтернативное написание инстукции. В левой колони оригинальное. Можно
пользоват как оригинальное так и альтернативное. Здесь только список
алтернативных инструкции.

        CPA CPB CPD
        LDA LDB LDD
        ORA ORB
        PHA PHB
        PLA PLB
        STA STB STD
        XORA XORB

        PHX PHY
        PLX PLY

  Пример:
                ldaa    #123
                lda     #123
                ldab    #124
                ldb     #124