Этим Вы окажете большую помощь науке и медицине. См. подробнее: http://solidstate.karelia.ru/~yura/pyldin/yura/computing.htm |
Научно-изследователска и производствена лаборатория "ПРОГРАМНО ОСИГУРЯВАНЕ" София ---------------------------------------------------------------- IBM-PC / ПЪЛДИН К Р О С - А С Е М Б Л Е Р UniCROSS версия 3.6 Р Ъ К О В О Д С Т В О З А П О Т Р Е Б И Т Е Л Я редакция 3 София - 1992 Copyright (с) 1988-1992 НИПЛ"Програмно осигуряване", София, България UniDOS, UniBIOS, UniED, UniASM, UniCROSS, UniPASCAL и UniBASIC са запазени търговски марки на НИПЛ "Програмно осигуряване". "Пълдин" е запазена търговска марка на Сдружение "АБАКУС". Настоящият документ, както и произволна негова част, не може да бъде копиран, предаван или включван в информационно-спавочни системи без предварителното писмено съгласие на НИПЛ "Програмно осигуряване". Всички права върху операционната система UniDOS, базовата входно-изходна система UniBIOS, текстовия редактор UniED, асемблерите UniASM и UniCROSS, интерпретатора UniBASIC, интерпретатора и компилатора UniPASCAL, както и върху произволна тяхна част са запазени. НИПЛ "Програмно осигуряване" не носи никаква отговорност за работоспособността на програмните продукти в случаите на нерагламентиран презапис или ползване. Програмен дизайн и реализация: н.с.Иво Ненов, н.с.Орлин Шопов, н.с.Георги Петров Автор на ръководството и редакция: к.т.н. инж.Недялко Тодоров Предпечатна подготовка: ........................ НИПЛ "Програмно осигуряване" благодари на всеки, който изпрати своите забележки, препоръки и делови предложения на следния адрес: НИПЛ"Програмно осигуряване" бул. "Тракия" - 125, бл.1 София 1113 телефон: (02) 706158, 706248, 706317 телефакс: (02) 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.2. Отчетен (listing) файл 5.3. Диагностичен (error's) файл 5.4. Обектен (object) файл 5.5. PGM-файл 6. СТАРТИРАНЕ НА UniCROSS 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. За процеса на работа на UniCROSS са използвани термините "транслация" и "асемблиране". Терминът "символ" се употребява за означаване на "графичен (изобразим) символ" и за "символ на езика асемблер". Интерпретацията на термина се определя от контекста. Документът е съставен изхождайки от предположението, че читателят вече е усвоил програмирането на машинен код на процесора, а така също и основните понятия и похвати за работа с операционната система. ТОВА РЪКОВОДСТВО НЕ Е УЧЕБНИК по програмиране на асемблер. При евентуално създаване на нови версии на програмния продукт необходимите изменения и допълнения към това ръководство ще бъдат записани в текстовия файл READ_ME.CRS, включен в дистрибутивния комплект на програмния продукт UniCROSS. Пълната информация за компютъра ПЪЛДИН и операционната система UniDOS се съдържа в документа "Ръководство за потребителя на UniDOS, UniBIOS и UniED". В описанието на UniCROSS са използвани следните означения: < ... > - задължителна част на конструкция - на посоченото място се въвежда конкретна стойност на описаното. Например, <име_на_файл> означава, че задължително трябва да се въведе име на конкретен файл. [ ... ] - незадължителна част на конструкция. { ... } - в зависимост от конкретния случай - задължителна или незадължителна част на конструкция. Например, параметър в зависимост от конкретната команда. 2. СИНТАКСИЧНИ КАТЕГОРИИ НА АСЕМБЛЕРА 2.1. СИМВОЛИ Символ в асемблера се нарича определено в програмата име, на което е съпоставено (дадено като стойност) цяло шестнайсетично число без знак. Символ се дефинира като етикет или чрез директива за даване на стойност. Имената трябва да бъдат съставени от латински букви (малките са неразличими от главните), цифри и символа за подчертан интервал "_". Дължината на името е ограничено само от дължината на програмния ред, но СЕ ОТЧИТАТ САМО ПЪРВИТЕ 16 СИМВОЛА. Главните и малки букви са неразличими. Например, символите loop, LOOP и LooP са неразличими. В зависимост от валидността в рамките на една програма символите се разделят на ГЛОБАЛНИ и ЛОКАЛНИ. Глобалните символи са валидни (определени) в цялата програма. Локалните символи имат смисъл (приложими са, определени са) само в процедурата, където са определени. Това позволява едно и също име да има различни стойности в различни процедури. С оглед обработката на обектния модул от свързващ редактор, част от символите (етикетите) могат да бъдат обявени чрез съответните директиви (вж. по-надолу EXTERN и PUBLIC) за ВЪНШНИ или ВЪТРЕШНИ. ВЪНШНИ са символи, определени в друг (не текущия) модул. Техните стойности не са известни по време на транслацията. Външни символи могат да бъдат използвани само там, където могат да бъдат използвани недефинирани символи. Външните символи не могат да бъдат използвани в инструкции с относителна адресация. ВЪТРЕШНИ са символи, определени в текущия модул и предназначени за използване в друг модул. Няма ограничения за използване на вътрешните символи в рамките на текущия модул. 2.2. КОНСТАНТИ Константите в асемблера имат 8 или 16 битово вътрешно представяне в един или два последователни байта. Допустимо е използването на следните видове константи: - ДЕСЕТИЧНО ЧИСЛО Пример: 123 234 345 - ШЕСТНАЙСЕТИЧНО ЧИСЛО - предхожда се от доларов знак Пример: $AB $12 $F2 - ДВОИЧНО ЧИСЛО - предхожда се от знак за процент Пример: %11 %0001 %1001 - ЕДИНИЧЕН ГРАФИЧЕН СИМВОЛ - огражда се с апострофи. На константата се дава стойност, равна на ASCII-кода на графичния символ. Ако графичният символ е апостроф, то той се удвоява между ограничителните апострофи. Пример: 'ш' '&' '''' 2.3. ИЗРАЗИ Израз наричаме последователност от символи и/или константи и/или символа "*", използван за означаване на текущата стойност на брояча на адреси, свързани с операции. Стойността на израз има 16-битово вътрешно представяне в два последователни байта. Допустими са следните операции (в скоби са посочени съответните им графични символи) по реда на приоритета (от най-високия към най-ниския приоритет): Приоритет 1: - скоби ( и ) Приоритет 2: - логическо отрицание NOT - (!) - смяна на знака - (-) Приоритет 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). Обектните модули след съответна обработка могат да бъдат доведени до състояние на преместваеми изпълними програми (program). Имената на файловете се определят по общите правила на операционната система UniDOS. Типът на резултатния файл се определя от използваното разширение на името при спазване на следните ограничения: - ако във входния програмен модул се съдържа директивата ORG, то резултатният файл съдържа непреместваема изпълнима програма (CMD); - ако във входния програмен модул се съдържа директивата EXTERN, то резултатният файл съдържа обектен модул (OBJ). Използват се следните разширения на файловите имена: source: ASM listing: LST error's: ERR rezult: object: OBJ command: CMD program: PGM 5.1. ВХОДЕН (SOURCE) ФАЙЛ Входният файл се обработва поредово, като всеки ред може да съдържа само една инструкция. Максималната дължина на програмен ред е 255 символа. Празен ред се счита за коментарен ред и не се обработва от крос-транслатора. Всеки програмен ред се състои от 4 полета, разделени с поне един интервал или табулация: [ [етикет] <операция> {операнд} ] [коментар] При синтаксичния анализ главните и малки букви са неразличими. ПОЛЕТО ЗА ЕТИКЕТИ е първо в програмния ред винаги, когато първият символ не е интервал, табулация или ";". Етикетът се разглежда като определен в програмата символ със стойност, равна на текущата стойност на брояча на адресите. Броячът на адресите по време на транслация определя адреса или отместването на инструкцията в паметта. Началната стойност на брояча е равен на началния адрес на програмата. След всеки обработен програмен ред стойността на брояча се увеличава с дължината на инструкцията. По такъв начин етикетът представлява адрес на следващата след него инструкция. Това позволява осъществяването на програмни преходи без да се пресмята адресът. Този похват прави програмата независима от разположението й в паметта на компютъра. В UniCROSS броячът на адреси се отбелязва със символа звезда "*". ПОЛЕТО ЗА ОПЕРАЦИЯ съдържа мнемониката на машинна команда (всички команди на процесора СМ601 са дадени в съответното приложение), команда INT xx за изпълнение на системна функция на UniDOS с номер xx (xx - шестнайсетично число), или директива на транслатора. Ако е записана команда, то се генерира съответния й машинен код. Ако е записана директива, то тя се изпълнява. Ако машинната команда е двуоперандна, обозначението на първия операнд (акумулатор A или B, или регистър X) се добавя към мнемониката на командата. Съдържанието на ПОЛЕТО ЗА ОПЕРАНД се определя от операцията. Някои операции нямат операнди. Операндите могат да бъдат адреси, изчисляеми изрази или списъци. Първи символ в ПОЛЕТО ЗА КОМЕНТАР трябва да бъде символът ";". След него могат да се запишат произволни символи. Те не влияят на процеса на транслация и на генерирания код. 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 world !', 0 6 0113 end Ако при обработка на програмен ред бъде открита грешка, съответното ДИАГНОСТИЧНО СЪОБЩЕНИЕ ще бъде изведено на следващия ред на листинга. 5.3. ДИАГНОСТИЧЕН (ERROR'S) ФАЙЛ По време на работа UniCROSS извежда диагностични съобщения за евентуално открити грешки текущо на екрана, в отчетния (listing) файл, ако е предвидена генерацията му, и в диагностичен файл. Името на диагностичния файл се формира от името на входния файл и разширение .ERR. Диагностичните съобщения имат следния формат: <име_входен_файл>(<номер_на_ред>): ERROR: <текст> Текстовете на съобщенията са дадени в приложение B. 5.4. ОБЕКТЕН (OBJECT) ФАЙЛ Обектният файл има следната структура: АДРЕС СЪДЪРЖАНИЕ ---------------------------------------------------------------- $00 (W) $5AA5; $02 (W) $0001 (номер на версията); $04 (W) брой на вътрешните (PUBLIC) символи; $06 (W) брой на външните (EXTERN) символи; $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) отместване на входната точка от началото на кода; $0A (W) дължина на данните; $0C-$0F 0 $10 начало на таблицата на отместването от началото на кода на байтовете на релокацията. 6. СТАРТИРАНЕ НА UniCROSS Стартирането на транслатора UniCROSS се осъществява чрез следната команда на операционната система UniDOS: UNICROSS <source> [ <listing> [ <result> ] ] Незадължителните параметри могат да бъдат заменени със символа точка и запетая - ";". Ако това е направено, отчетен файл не се генерира, а резултатният файл има име, съвпадащо с името на входния файл и разширение, съответстващо на съответния тип резултатен файл. Разширението на името на резултатния файл определя типа на резултата от работата на крос-асемблера: OBJ - обектен модул; PGM - преместваема изпълнима програма; CMD - непреместваема изпълнима програма, при спазване на описаните в т.5 ограничения. Крос-асемблера може да бъде стартиран и без параметри чрез командата: 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 Операциите с ПРЯКА адресация обхващат само нулевата страница от паметта (адреси в интервала [$00 ... $FF]) и имат синтаксис: <инструкция> <израз> Изразът трябва да има стойност в интервала [0, 255]. Примери: ldab 0 stab $20 stx $FE РАЗШИРЕНАТА адресация се отличава от пряката само по това, че стойността на израза може да отговаря на всеки достъпен адрес от паметта на компютъра. Примеры: ldaa $2000 stx $1FFE Операциите с ИНДЕКСНА адресация имат синтаксис: <инструкция> X,<израз> <инструкция> <израз>,X <инструкция> X В третия случай се счита, че изразът има стойност 0. Примери: ldaa X adda X,1 ldx X,field1 ldab $33,X Операциите с ОТНОСИТЕЛНА адресация имат синтаксис: <инструкция> <израз> Към тази група се отнасят операциите за условен и безусловен преход, с изключение на JSR и JMP. В качеството на операнд се взема стойността на израза минус текущата стойност на брояча на адресите. Стойността на израза трябва да бъде в интервала [-129, +125]. Примери: bra exit bne not_equ 8. ДИРЕКТИВИ Внимание! Директивите за условна компилация са описани в глава 4. 8.1. ДИРЕКТИВИ ЗА ОПРЕДЕЛЯНЕ НА СИМВОЛИ 8.1.1. EQU - даване на стойност Синтаксис: <етикет> EQU <израз> <етикет> = <израз> Предназначение: определяне на символ (етикет) - символът получава тип и стойност, равни на тези на резултата от изчисляване на израза. Забележки: Символът не трябва да бъде определен до изпълнението на директивата и в израза не може да бъде включен външен символ. Примери: code_start = $100 lo_byte EQU hi_byte + 1 8.1.2. 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 <списък_етикети> Предназначение: обявяване на външни за модула символи. Забележки: ако в програмния модул се съдържа тази директива, то в резултат на асемблирането му се получава обектен модул (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 <списък_от_изрази> Предназначение: запис в обектния код на еднa или повече думи (старши байт, младши байт), всяка от които съдържа стойността на поредния израз в списъка. Забележки: Може да се използва САМО аритметичен израз. Примери: 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>=$00. Забележки: В изразите не могат да участват етикети Ако стойността на <израз_2> да има дължина над 1 байт, то се отчита младшия байт на стойността. Примери: buffer DS $200 DS $10, 32 8.2.4. CHKSUM - контролна сума Синтаксис: CHKSUM Предназначение: формиране и запис в непреместваема изпълнима програма (CMD) на контролен байт, осигуряващ нулева контролна сума, изчислявана чрез еднобайтово събиране без пренос. Забележки: Директивата се препоръчва при асемблиране на програми, предназначени за запис в ROM. 8.3. ДИРЕКТИВИ ЗА УПРАВЛЕНИЕ НА ТРАНСЛАЦИЯТА 8.3.1. SECT - начало на фиктивна секция Синтаксис: SECT [израз] Предназначение: формиране на начало на фиктивна секция от адрес, равен на стойността на израза или равен на текущата стойност на адресния брояч, ако изразът е пропуснат. Забележки: Краят на фиктивната секция се формира с директивата ENDS. В рамките на фиктивна секция не се генерира изпълним код. Изразът не може да съдържа неопределени и/или външни символи. Фиктивните секции не могат да бъдат вложени. 8.3.2. ENDS - край на фиктивна секция Синтаксис: ENDS Предназначение: формиране на край на фиктивна секция. Забележки: Началото на фиктивна секция се формира с директива SECTION. След изпълнението на директивата броячът на адреси получава стойността, която е имал преди изпълнението на съответната директива за формиране на фиктивна секция. Използването на ENDS извън фиктивна секция е недопустимо. 8.3.3. PROC - начало на процедура Синтаксис: <етикет> PROC Предназначение: формиране на начало на процедура. Забележки: Краят на процедурата се формира с директивата ENDP. Всяка процедура може да съдържа неограничен брой вложени процедури. Всички символи, определени в една процедура и необявени с директива GLOBAL за глобални, се считат локални. Търсенето на символ започва в текущата процедура, а след това - в родителските (обхващащи) процедури. 8.3.4. ENDP - край на процедура Синтаксис: ENDP Предназначение: формиране на край на процедура. Забележки: Началото на процедура се формира с директива PROC. 8.3.5. END - край на програма Синтаксис: END [израз] Предназначение: формиране край на програмата със стартов адрес, равен на стойността на израза (в случай на асемблиране на обектни модули OBJ или преместваеми програми PGM). Забележки: Ако изразът е пропуснат, стартовият адрес съответства на началото на програмата. Директивата не е задължителна. Текстът след директивата се игнорира. 8.3.6. ORG - даване стойност на брояча на адреси Синтаксис: ORG <израз> Предназначение: даване на брояча на адреси на стойност, равна на стойността на израза. Забележки: Забранено е използването на директивата във фиктивна секция. Изразът не трябва да включва етикети и/или неопределени и/или външни символи и неговата стойност трябва да бъде константа. Ако в програмния модул се съдържа тази директива, то в резултат на асемблирането му се получава непреместваема изпълнима програма (CMD). 8.3.7. ERROR - възбуждане на състояние ГРЕШКА Синтаксис: ERROR <израз> Предназначение: преминаване към състояние ГРЕШКА, ако изразът има ненулева стойност. Забележки: Изразът трябва да бъде от абсолютен тип и в него не могат да участват неопределени и външни символи. Пример: ERROR * % $100 ; грешка, ако текущата стойност ; на брояча не е равна на граница ; на страница от паметта 5.3.8. RADIX - изменение на бройната система Синтаксис: RADIX <израз> Предназначение: преминаване към бройна система с основа, равна на стойността на израза. Забележки: Допустими са стойности на израза в интервала [2 ... 16]. Пример: ldaa #$3F RADIX 16 ldaa #3F 5.3.9. 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 вид адресация L флаг L L код L действие наL-----------------------------------L L L командата L Inh LRel 2LImm 2LDir 2LInd 2LExt 3LHINZVCL --------------------------------------------------------------- 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. - Неправилно използване на директивата CHKSUM. - директивата CHKSUM е използвана два пъти или е използвана при генериране на преместваема изпълнима програма (PGM). 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 в режим на генерация на преместваема изпълнима програма (PGM). Output buffer overflow. - Препълване на буфера на резултатния файл - дължината на резултатния файл не не трябва да бъде по-голяма от 32КВ. Proc nesting error. - Неправилно влагане на процедури. PUBLIC not allowed in not relative mode. - Директивата PUBLIC е забранена в случай на генериране на непреместваема изпълнима програма (CMD-файл). Redefinition of symbol <етикет>. - Предефиниране на етикет. There is no memory available. - Няма повече достъпна (свободна) памет. Undefined identifier <име>. - Неопределен идентификатор <име>. Unexpected directive END. - Неправилно използване на директивата END - вероятно директивата END се намира във вложен файл. User error. - Потребителска грешка - съобщението се извежда при изпълнение на директивата ERROR, ако стойността на операнда е различна от нула. Приложение C - СВЪРЗВАЩ РЕДАКТОР ULINK В състава на операционната система UniDOS за микрокомпютрите от фамилията "Пълдин" е включен свързващият редактор ULINK, с който отделно асемблираните обектни модули могат да бъдат свързани в изпълнима програма. Стартирането на свързващия редактор ULINK се осъществява чрез следната команда на UniDOS: ULINK [/[c][p]]<modules> където: c - опция за формиране (ако е възможно) на CMD-резултатен файл. Ако опцията е пропусната, то се формира PGM-резултатен файл. p - опция за изравняване на обектните модули на границата на страница. <modules> - списък на обектни модули или библиотеки, които трябва да бъдат свързани в изпълнима програма. Имената в списъка са без разширение. По премълчаване се приема разширение OBJ за обектен модул и LIB - за библиотеки. В резултат от работата на редактора се създава изпълнима програма с име, съвпадащо с името на модула, съдържащ директивата MAIN и с разширение на името CMD или PGM, в зависимост от наличието или отсъствието на опцията /c. Всеки обектен модул се състои от сегмент на кода и разположен непосредствено след него сегмент на данни. Сегментът на данните може да включва САМО неинициализирани данни. За създаване на такъв сегмент се използва директивата SECTION в началото на сегмента. В процеса на работа на редактора съответните сегменти на всички обектни модули се обединяват и се създават обединени сегменти на код и данни, отново разположени непосредствено един след друг. В обединените сегменти се включват САМО сегменти от обектните модули (на код и данни), към които има обръщение. Ако се генерира CMD-файл, програмата трябва да съдържа проверка за съществуване на достатъчна за разполагане на сегмента данни памет. При генериране на PGM-файл такова съответствие е гарантирано. По време на работата на свързващия редактор могат да бъдат получени следните ДИАГНОСТИЧНИ СЪОБЩЕНИЯ: Code too large - обобщеният сегмент на кода е по-дълъг от 64 KB Data too large - обобщеният сегмент на данните е по-дълъг от 64 KB Error in object table - грешка в таблицата на отместванията на обектния модул File too large - модулът е по-дълъг от 64 KB 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 - грешка при запис на файл