Этим Вы окажете большую помощь науке и медицине. См. подробнее: http://solidstate.karelia.ru/~yura/pyldin/yura/computing.htm |
>>>>>>> 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