Этим Вы окажете большую помощь науке и медицине. См. подробнее: http://solidstate.karelia.ru/~yura/pyldin/yura/computing.htm |
Научно-изследователска и производствена лаборатория "ПРОГРАМНО ОСИГУРЯВАНЕ" София ---------------------------------------------------------------- ПЕРСОНАЛЕН МИКРОКОМПЮТЪР "ПЪЛДИН" А С Е М Б Л Е Р UniASM версия 2.04 Р Ъ К О В О Д С Т В О З А П О Т Р Е Б И Т Е Л Я редакция 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. УВОД В програмирането терминът "асемблер" се употребява в смисъл на машинно-ориентиран език от ниско ниво и на транслатор на програми, написани на този език. Всеки компютър, или по-точно - всеки процесор, има свой собствен асемблер. Този документ е ръководство за потребителя на транслатора UniASM на езика асемблер за микропроцесора СМ601 (аналог на процесора MC6800). UniASM е предназначен за работа в среда на операционната система UniDOS на микрокомпютрите от фамилията "ПЪЛДИН". В този документ, като правило, под "асемблер" се разбира програмния продукт UniASM. За процеса на работа на UniASM са използвани термините "транслация" и "асемблиране". Терминът "символ" се употребява за означаване на "графичен (избразим) символ" и за "символ на езика асемблер". Интерпретацията на термина се определя от контекста. Документът е съставен изхождайки от предположението, че читателят вече е усвоил програмирането на машинен код на процесора, а така също и основните понятия и похвати за работа с операционната система. ТОВА РЪКОВОДСТВО НЕ Е УЧЕБНИК по програмиране на асемблер. При евентуално създаване на нови версии на програмния продукт необходимите изменения и допълнения към това ръководство ще бъдат записани в текстовия файл READ_ME.ASM, включен в дистрибутивния комплект на програмния продукт UniASM. Пълната информация за компютъра ПЪЛДИН и операционната система UniDOS се съдържа в документа "Ръководство за потребителя на UniDOS, UniBIOS и UniED". В описанието на UniASM са използвани следните означения: < ... > - задължителна част на конструкция - на посоченото място се въвежда конкретна стойност на описаното. Например, <име_на_файл> означава, че задължително трябва да се въведе име на конкретен файл. [ ... ] - незадължителна част на конструкция. { ... } - в зависимост от конкретния случай - задължителна или незадължителна част на конструкция. Например, параметър в зависимост от конкретната команда. ВНИМАНИЕ! В дистрибутивния комплект е включена и програмата UASM.COM, предназначена за работа в среда на операционната система MS DOS на компютри от фамилията IBM-PC. Тя представлява крос-компилатор на асемблер за ПЪЛДИН - т.е. позволява създаването на асемблерски програми, предназначени за ПЪЛДИН, работейки на компютри IBM-PC. Всичко, казано за продукта UniASM, се отнася и за кроскомпилатора UASM.COM. 2. СИНТАКСИЧНИ КАТЕГОРИИ НА АСЕМБЛЕРА 2.1. СИМВОЛИ Символ в асемблера се нарича определено в програмата име, на което е съпоставено (дадено като стойност) цяло шестнайсетично число без знак. Символ се дефинира като етикет или чрез директива за даване на стойност. Имената трябва да бъдат съставени от латински букви (малките са неразличими от главните), цифри и символа за подчертан интервал "_". Дължината на името е ограничено само от дължината на програмния ред, но СЕ ОТЧИТАТ САМО ПЪРВИТЕ 8 СИМВОЛА. Например, символите abcdefgh111 и abcdefgh222 са неразличими. Неразличими са и символите loop, LOOP и LooP. Разглежданата версия на UniASM допуска в една програма да бъдат определени до 1900 символа. В зависимост от валидността в рамките на една програма символите се разделят на ГЛОБАЛНИ и ЛОКАЛНИ. Глобалните символи са валидни (определени) в цялата програма. Техните имена трябва да започват с латинска буква. Локалните символи имат смисъл (приложими са, определени са) само в определена част от програмата, наричана "блок от локални символи". Това позволява едно и също име да има различни стойности в различни части на програмата. Формално локалните символи се различават от глобалните по това, че техните имена се предшестват от двуеточие ":". Двуеточието не се смята част от първите 8 различими символа на името. Блокът от локални символи се ограничава от два глобални етикета или от началото или края на програмата. В един блок един локален символ може да бъде определен само един път. Глобални символи, определени чрез директивите за даване на стойност "=" и "==" (вж. по-долу), не ограничават блок от локални символи - т.е. в рамките на блока локални символи могат да бъдат определени и глобални символи. В един блок локални символи могат да бъдат определени до 255 локални символа. По време на транслацията за локалните символи не се отделя памет, което позволява транслирането на големи програми. Добрият стил на програмиране изисква използването на глобални символи като имена на процедури, променливи и константи, а на локални символи - като етикети в рамките на отделни процедури. Пример за използване на локални символи: Dummy ; начало на блок локални символи ; входната точка се намира по-надолу :Find INX LDAA X BEQ :Found CMPA #'\' BNE :Find Parse = . ; входна точка - не ограничава блок ; локални символи STX :Tmp BRA :Find :Found LDX :Tmp LDAB #'.' :Scan INX LDAA X BEQ :Exit CBA BNE :Scan :Exit STAB X RTS :Tmp DS 1 С оглед обработката на обектния модул от свързващ редактор, част (до 24) от ГЛОБАЛНИТЕ символи ОТ ОТНОСИТЕЛЕН ТИП могат да бъдат обявени чрез съответните директиви (вж. по-надолу EXT и ENT) за ВЪНШНИ или ВЪТРЕШНИ. ВЪНШНИ са символи, определени в друг (не текущия) модул. Техните стойности не са известни по време на транслацията. Външни символи могат да бъдат използвани само там, където могат да бъдат използвани недефинирани символи. Външните символи не могат да бъдат използвани в инструкции с относителна адресация. ВЪТРЕШНИ са символи. определени в текущия модул и предназначени за използване в друг модул. Няма ограничения за използване на вътрешните символи в рамките на текущия модул. Очевидно, вътрешни и външни символи могат да бъдат използвани САМО, ако при стартирането на UniASM е указано генериране на ОБЕКТЕН резултатен файл (OBJ), но НЕ и когато е предвидено генерирането на непреместваема изпълнима програма (CMD резултатен файл). 2.2. КОНСТАНТИ Константите в асемблера имат 8 или 16 битово вътрешно представяне в един или два последователни байта. Допустимо е използването на следните видове константи: - ДЕСЕТИЧНО ЧИСЛО Пример: 123 234 345 - ШЕСТНАЙСЕТИЧНО ЧИСЛО - предхожда се от доларов знак Пример: $AB $12 $F2 - ДВОИЧНО ЧИСЛО - предхожда се от знак за процент Пример: %11 %0001 %1001 - ЕДИНИЧЕН ГРАФИЧЕН СИМВОЛ - огражда се с апострофи. На константата се дава стойност, равна на ASCII-кода на графичния символ. Ако графичният символ е апостроф, то той се удвоява между ограничителните апострофи. Пример: 'ш' '&' '''' - ДВОЕН ГРАФИЧЕН СИМВОЛ - огражда се с апострофи. Дължината на константата е една дума като в старшия байт се записва ASCII-кода на първия графичен символ, а в младшия - на втория графичен символ. 2.3. ИЗРАЗИ Израз наричаме последователност от символи и/или константи и/или символа ".", използван за означаване на текущата стойност на брояча на адреси, свързани с операции. Стойността на израз има 16-битово вътрешно представяне в два последователни байта. Изразът може да започва със знака "<", ако е необходимо като стойност на израз да се отчита старшия байт на резултата, или със знака ">", ако е необходимо като стойност на израз да се отчита младшия байт на резултата. Допустими са следните операции (в скоби са посочени съответните им графични символи): - смяна на знака (-); - събиране (+); - изваждане (-); - умножение (*); - деление (/); - логическо И (&); - логическо ИЛИ (!). След изпълнението на операцията се отчитат само младшите два байта от получения резултат. ВНИМАНИЕ! Всички операции имат ЕДНАКЪВ ПРИОРИТЕТ и се изпълняват последователно отляво надясно. Последователността на изпълнение на операциите може да бъде изменена чрез употреба на кръгли скоби. Операции не могат да участват в изрази, съдържащи външен или неопределен символ. В някои изрази изобщо не е разрешено използване на такива символи. Ако външен или неопределен символ участва в израз - операнд на машинна инструкция, позволяваща пряка и разширена адресация, то за тази инструкция ще бъде използвана разширена адресация. Това води до добавяне на излишна нула в обектния код. По тази причина използването на външни или неопределени символи в такива изрази НЕ СЕ ПРЕПОРЪЧВА! Примери на изрази: 2+2 Label1 - Label2 2 * Label + $231 'a' + 'A' 'x' & %111 >Table <Table 2.4. СПИСЪЦИ Списък наричаме последователност от изрази, разделени със запетаи. Ако два съседни израза в списък са графични символи, поставени в апострофи, то тези изрази могат да бъдат обединени. Ако апострофът е част от списък, то той трябва да бъде удвоен. Например, списъкът ( 'st','r','in','g' ) може да бъде записан във вида ( 'string' ). ВНИМАНИЕ! Това правило не може да бъде приложено в случай на използване на директивата DW. Примери на списъци: 'This is a String' 'This is another String',0 4,'tmp' 'Five o''clock a.m.',$d,$a 3. ТИП НА ПРОГРАМНИТЕ СЕКЦИИ И ВЕЛИЧИНИТЕ За краткост символите, константите и изразите в асемблера ще наричаме "величини". Величините се характеризират не само със стойност, но и с тип: относителен или абсолютен. От тези типове може да бъде и всяка от програмните секции. От абсолютен тип е величина, чиято стойност е фиксиран адрес от паметта или число. По тази причина константите са винаги абсолютни величини. От относителен тип е величина, чиято стойност е неопределен по време на транслацията адрес от паметта, който ще бъде определен по време на зареждането на програмата или по време на обработка на обектния модул от свързващия редактор. 3.1. ТИП НА ПРОГРАМНА СЕКЦИЯ Типът на програмна секция е абсолютен или относителен в зависимост от това, дали ще се изпълнява от фиксиран адрес от паметта или не. Формирането на секция се осъществява чрез описаните по-долу директиви ORG и SECT. Секцията приема типа на израза, използван като параметър на директивата за създаване на секция. При транслиране на относителна секция UniASM генерира информацията, необходима по време на зареждането на програмата или по време на обработката на обектния модул от свързващия редактор. 3.2. ТИП НА СИМВОЛ Типът на символ се определя по следните правила: 1. Ако символът е дефиниран чрез директива за даване на стойност, то той получава типа на съответния израз; 2. Етикетите и символът на брояча на адреси имат еднакъв с текущата програмна секция тип; 3. Вътрешните и външни символи са от винаги от относителен тип. 3.3. ТИП НА ИЗРАЗ Типът на израз се определя от операцията и типовете на операндите по следните правила: ------------------------------------------------------ Операнд 1 Операция Операнд 2 Резултат ------------------------------------------------------ Относителен - Относителен = Абсолютен; Относителен - Абсолютен = Относителен; Абсолютен - Относителен = Грешка; Относителен + Относителен = Грешка; Относителен + Абсолютен = Относителен; Абсолютен + Относителен = Относителен; Абсолютен <всяка> Абсолютен = Абсолютен. ВНИМАНИЕ! Други, освен показаните в таблицата, комбинации от операнди и операции СА НЕДОПУСТИМИ и изразите, където евентуално бъдат срещнати, ще имат резултат ГРЕШКА! Ще напомним още един път, че последователността на операциите съществено влияе на резултата. Това се демонстрира от следната таблица, където Label1, Label2, Label3 и Label4 са ОТНОСИТЕЛНИ символи: -------------------------------------------------------- израз резултат -------------------------------------------------------- Label1 + Label3 - Label2 - Label4 ГРЕШКА Label1 + (Label3 - Label2) - Label4 абсолютен Label1 - Label2 + Label3 - Label4 абсолютен 4. ФАЙЛОВЕ НА UniASM UniASM работи с три вида файлове: - входни (source), съдържащи асемблерски програмен текст в изходен вид; - отчетни (listing), съдържащи протокол на процеса на транслация; - изходни (output), съдържащи обектен модул (object) или непреместваема изпълнима програма (command). UniASM като резултат от работата си генерира алтернативно или отчетен или изходен файл. Затова в по-нататък текста тези файлове са наречени общо резултатни (result). Ако при стартирането на UniASM не е изискано генерирането на отчетен резултатен файл (listing), при липса на директива CMD се генерира OBJ-резултатен файл. Обектните модули след съответна обработка могат да бъдат доведени до състояние на преместваеми изпълними програми (program). Имената на файловете се определят по общите правила на операционната система UniDOS. По премълчаване се използват следните разширения на файловите имена: source: 601 listing: LST object: OBJ command: CMD program: PGM Ако в пълното име на файла не трябва да бъде включено разширение, след името трябва да бъде въведена точка. 4.1. ВХОДЕН (SOURCE) ФАЙЛ Входният файл се обработва поредово, като всеки ред може да съдържа само една инструкция. Максималната дължина на програмен ред е 80 символа. Празен ред и ред, в който първият символ е ";", се считат коментарни редове и не се обработват от транслаторите. Всеки програмен ред се състои от 4 полета, разделени с поне един интервал или табулация: [етикет] <операция> {операнд} [коментар] При синтаксичния анализ главните и малки букви са неразличими. ПОЛЕТО ЗА ЕТИКЕТИ е първо в програмния ред винаги, когато първият символ не е интервал, табулация или ";". Етикетът се разглежда като определен в програмата символ със стойност, равна на текущата стойност на брояча на адресите. Броячът на адресите по време на транслация определя адреса или отместването на инструкцията в паметта. Началната стойност на брояча е равен на началния адрес на програмата. След всеки обработен програмен ред стойността на брояча се увеличава с дължината на инструкцията. По такъв начин етикетът представлява адрес на следващата след него инструкция. Това позволява осъществяването на програмни преходи без да се пресмята адресът. Този похват прави програмата независима от разположението й в паметта на компютъра. В UniASM броячът на адреси се отбелязва със символа точка ".". ПОЛЕТО ЗА ОПЕРАЦИЯ съдържа мнемониката на машинна команда (всички команди на процесора СМ601 са дадени в съответното приложение), команда INT xx за изпълнение на системна функция на UniDOS с номер xx (xx - шестнайсетично число), или директива на транслатора. Ако е записана команда, то се генерира съответния й машинен код. Ако е записана директива, то тя се изпълнява. Ако машинната команда е двуоперандна, обозначението на първия операнд (акумулатор A или B, или регистър X) се добавя към мнемониката на командата. В UniASM освен стандартните са допустими и следните мнемоники (на същия ред са посочени съответните им стандартни мнемоники): BHS --> BCC BLO --> BCS LSL --> ASL LSLA --> ASLA LSLB --> ASLB Съдържанието на ПОЛЕТО ЗА ОПЕРАНД се определя от операцията. Операндите могат да бъдат адреси, изчисляеми изрази или списъци. Някои операции нямат операнди. Първи символ в ПОЛЕТО ЗА КОМЕНТАР трябва да бъде символът ";". След него могат да се запишат произволни символи. Те не влияят на процеса на транслация и на генерирания код. 4.2. ОТЧЕТЕН (LISTING) ФАЙЛ UniASM генерира листинг със следния формат: <адрес> <машинен код> <номер на ред> <изходен текст> Ако машинният код е по-дълъг от три байта, то се извеждат само първите три байта. Ако при обработка на програмен ред бъде открита грешка, съответното ДИАГНОСТИЧНО СЪОБЩЕНИЕ ще бъде изведено на следващия ред на листинга. В края на листинга се извежда таблица на глобалните символи и техните стойности. Неизползваните символи са отбелязани със знак "?", недефинираните символи - със знак "!", а външните - със знак "*". Локалните символи не се включват в символната таблица. 4.3. ОБЕКТЕН (OBJECT) ФАЙЛ Обектният файл има следната структура: АДРЕС СЪДЪРЖАНИЕ ---------------------------------------------------------------- $00 (W) $5AA5; $02 (W) $0001 (номер на версията); $04 (W) брой на вътрешните (ENT) символи; $06 (W) брой на външните (EXT) символи; $08 (W) дължина на сегмента на кода; $0A (L) отместване на кода от началото на файла; $0E (W) отместване на входната точка от началото на файла - $FFFF означава, че няма входна точка; $10 (W) дължина на сегмента на данните; $12-$1F 0; $20 - масив на вътрешните символи; - масив на външните символи; - код; (W) брой отмествания в масива на отместванията - масив на отместванията; (B) 0. Всеки елемент от масива на вътрешните символи има следния формат: $00-$0F - име (в ASCIIZ - завършва на 0); $10 (W) - стойност; $12 (W) - тип: >= 0 - относителен; < 0 - абсолютен. Всеки елемент от масива на външните символи има следния формат: $00-$0F - име (в ASCIIZ - завършва на 0); $10 (L) - 0. Отделните елементи от масива на отместванията трябва на бъдат разположени в нарастващ порядък на отместванията. Всеки елемент от масива на отместванията има следния формат: $00 (B) тип: < 0 - външен; >= 0 - не външен; бит 0 = LSB; бит 1 = MSB; Ако двата бита = 1 - WORD; $01 (W) - ако е външен символ - индекс в масива на външните символи; ако не е външен символ - стойност; $03 (W) - отместване спрямо началото на кода. Ако отместването е по-голямо от дължина на кода, то се счита, че това е елемент от данните. 5. СТАРТИРАНЕ НА UniASM Стартирането на транслатора UniASM се осъществява чрез следната команда на операционната система UniDOS: UASM [/l] <source> [result] Параметърът /l определя вида на result-файла. Ако е въведен, то се генерира отчетен (LST) резултатен файл. Ако не е въведен, то, в зависимост от наличието или отсъствието на директивата CMD в програмния текст, се генерира непреместваема изпълнима програма (CMD) или обектен модул (OBJ). ВНИМАНИЕ! Едновременното генериране на отчетен и изходен файл е невъзможно! Примери за правилно стартиране: uasm sample.asm => транслация на файла SAMPLE.ASM; резултатният файл SAMPLE.OBJ съдържа обектен код, ако не е използвана директивата CMD. uasm /l sample => транслация на файла SAMPLE.601; резултатният файл SAMPLE.LST съдържа листинг. uasm sample sample.cmd => транслация на файла SAMPLE.601; резултатният файл SAMPLE.CMD съдържа обектен код, ако не е използвана директивата CMD. Примери за неправилно стартиране: uasm /l sample.lst => съдържанието на входния файл SAMPLE.LST се губи. uasm sample sample.601 => съдържанието на входния файл SAMPLE.601 се губи. 6. АДРЕСАЦИЯ НА МИКРОПРОЦЕССОРА СМ 601 Микропроцесорът СМ 601 допуска 7 вида адресация, показани в следната таблица: ------------------------------------------------------------ Вид адресация Синтаксис Дължина Пример ------------------------------------------------------------ Вътрешна Inherent 1 CLC Акумулаторна Accumulator 1 CLRA Непосредствена Immediate #израз 2(3) LDAB #$FF Пряка Direct израз 2 LDAB 0 Разширена Extended израз 3 STAA $FFFF Индексна Indexed израз,Х 2 LDX 0,X Х,израз Относителна Relative израз 2 BRA . ВНИМАНИЕ ! В случай на индексна адресация е допустим синтаксис Х вместо Х,0 или 0,Х. Непосредствената адресация има дължина 3 байта само за инструкциите LDS и LDX. Адресации с дължина 2 байта, освен относителната адресация, изискват резултатът от изчисляване на израз да има дължина 1 байт. Относителната адресация изисква резултат от относителен тип в диапазона [.-130 .+125]. Тъй като пряката и разширена адресации имат еднакъв синтаксис, за команди, допускащи двата вида адресации, транслаторът определя вида на генерируемата адресация в зависимост от типа и стойността на израза. Ако в израза е включен НЕОПРЕДЕЛЕН СИМВОЛ, то транслаторът генерира РАЗШИРЕНА адресация. Ако независимо от стойността на израза е необходимо използването на разширена адресация, то непосредствено след мнемокода на операцията трябва да се въведе символ "*". Например: Lab = $F0 LDAA* Lab 7. ДИРЕКТИВИ 7.1. ДИРЕКТИВИ ЗА ОПРЕДЕЛЯНЕ НА СИМВОЛИ 7.1.1. EQU - даване на стойност Синтаксис: <символ> EQU <израз> <символ> = <израз> Предназначение: определяне на символ - символът получава тип и стойност, равни на тези на резултата от изчисляване на израза. Забележки: Символът не трябва да бъде определен до изпълнението на директивата и в израза не може да бъде включен външен символ. Директивата не ограничава блока на локалните символи. 7.1.2. == - преопределяне на символ Синтаксис: <символ> == <израз> Предназначение: преопределяне на вече определен символ - символът получава тип и стойност, равни на тези на резултата от изчисляване на израза. 7.1.3. EXT - обявявяне на външен символ Синтаксис: <символ> EXT Предназначение: обявяване на външен за модула символ - обявяваният символ получава относителен тип. Забележки: Обявяваният символ не трябва да бъде локален. Директивата може да се използва само, ако се създава OBJ-файл. 7.1.4. ENT - обявяване на вътрешен символ Синтаксис: <символ> ENT [израз] Предназначение: обявяване на вътрешен символ. Забележки: Директивата е приложима само при генериране на OBJ изходен файл. Обявяваният символ не трябва да бъде локален. Изразът трябва да бъде от относителен тип и не трябва да включва неопределен и/или външен символ. Ако не е въведен израз, то директивата трябва да се намира в относителна секция и символът получава стойност, равна на текущата стойност на брояча на адресите. 7.2. ДИРЕКТИВИ ЗА ОПРЕДЕЛЯНЕ НА ДАННИ 7.2.1. DFB - дефиниране на байт(ове) Синтаксис: DFB <списък_от_изрази> Предназначение: запис в обектния код на един или повече байта, всеки от които съдържа стойността на поредния израз в списъка. Забележки: Всеки израз трябва да има стойност в диапазона 0..255. 7.2.2. DW - дефиниране на дума(и) Синтаксис: DW <списък_от_изрази> Предназначение: запис в обектния код на една или повече думи (старши байт, младши байт), всяка от които съдържа стойността на поредния израз в списъка. Забележки: Kато израз не може да се използва символен низ. 7.2.3. DS - последователност от еднакви байтове Синтаксис: DS <израз_1> [,<израз_2>] Предназначение: област от паметта, дълга <израз_1> байта, се запълва със стойността на <израз_2>. По премълчаване <израз_2>=$00. Забележки: <израз_1> трябва да бъде от абсолютен тип и в него не трябва да участват неопределени и/или външни символи. Стойността на <израз_2> трябва да има дължина 1 байт. 7.2.4. ASC - последователност от различни байтове Синтаксис: ASC <списък_от_изрази> Предназначение: запис в обектния код на един или повече байта, всеки от които съдържа стойността на поредния израз в списъка. След списъка от стойности в паметта се записва нулев байт. Забележки: Всеки израз трябва да има стойност в диапазона 0..255. 7.2.5. STR - символен низ в паметта Синтаксис: STR <списък_от_изрази> Предназначение: запис в обектния код на един или повече байта, всеки от които съдържа стойността на поредния израз в списъка. Преди списъка от стойности в паметта се записва техния брой (дължината на символния низ). Забележки: Всеки израз трябва да има стойност в диапазона 0..255. 7.2.6. CHK - контролна сума Синтаксис: CHK Предназначение: формиране и запис на контролен байт, осигуряващ нулева контролна сума, изчислявана чрез еднобайтово събиране без пренос. Забележки: Директивата може да бъде използвана еднократно и се препоръчва се при асемблиране на програми, предназначени за запис в ROM. 7.3. ДИРЕКТИВИ ЗА УПРАВЛЕНИЕ НА ТРАНСЛАЦИЯТА 7.3.1. CMD - създаване на CMD-файл Синтаксис: CMD [израз] Предназначение: задаване на изходен файл тип CMD (непреместваем изпълним) с начален адрес, определен от стойността на израза. По премълчаване началният адрес е равен на $100. Забележки: Директивата трябва да се въведе ПРЕДИ определяне на първия символ и ПРЕДИ първата изпълнима инструкция. Ако такава директива не е въведена, то UniASM формира изходен файл от типа OBJ. 7.3.2. MAIN - определяне на стартов адрес Синтаксис: MAIN Предназначение: като стартов адрес (адрес на входна точка) се определя адресът на последното използване на директивата. Забележки: Използването на директивата MAIN след директивата CMD е безсмислено. 7.3.3. END - край на програма Синтаксис: END Предназначение: формиране край на програмата. Забележки: Текстът след инструкцията се игнорира. 7.3.4. ORG - начало/край на секция Синтаксис: ORG [израз] Предназначение: Ако е въведен израз - формиране начало на нова програмна секция с тип (абсолютен или относителен), съвпадащ с типа на израза и ЛОГИЧЕСКИ адрес, равен на стойността на израза; Ако не е въведен израз - формиране на край на текущата секция и връщане към предидущата - възстановяване типа на текущата секция и стойността на адресния брояч. Забележки: Забранено е използването на директивата във фиктивна секция. Допуска се влагане на секции на едно ниво. Изразът не трябва да включва неопределени и/или външни символи. 7.3.5. SECT - начало на фиктивна секция Синтаксис: SECT [израз] Предназначение: формиране на начало на фиктивна секция от адрес, равен на стойността на израза или равен на текущата стойност на адресния брояч, ако изразът е пропуснат. Забележки: Краят на фиктивната секция се формира с директивата ENDS. Изразът не може да съдържа неопределени и/или външни символи. Фиктивните секции не могат да бъдат вложени. Използването на SECT без ENDS вътре във фиктивна секция води до изменение на стойността на адресния брояч и типа на секцията. 7.3.6. ENDS - край на фиктивна секция Синтаксис: ENDS Предназначение: формиране на край на фиктивна секция. Забележки: Началото на фиктивна секция се формира с директива SECT. След изпълнението на директивата броячът на адреси получава стойността, която е имал преди изпълнението на съответната директива за формиране на фиктивна секция. Използването на ENDS извън фиктивна секция е без последствия. 7.3.7. ERR - възбуждане на състояние ГРЕШКА Синтаксис: ERR [израз] Предназначение: преминаване към състояние ГРЕШКА, ако изразът е пропуснат или има ненулева стойност. Забележки: Изразът трябва да бъде от абсолютен тип и в него не могат да участват неопределени и външни символи. 7.4. ДИРЕКТИВИ ЗА УПРАВЛЕНИЕ НА ЛИСТИНГА 7.4.1. LIST - включване/изключване на листинга Синтаксис: LIST [израз] Предназначение: включване (израз = 0) или изключване (израз <> 0) на листинга по време на асемблирането. Забележки: Изразът трябва да бъде от абсолютен тип и не трябва да съдържа неопределени или външни символи. Ако изразът е пропуснат, листингът се превключва алтернативно. Директивата не влияе на работата, ако при стартиране на UniASM не е въведен параметър /l. Въведена в края на програмата, директивата управлява извеждането на таблицата на символите. 7.4.2. PAGE - брой редове на страница от листинга Синтаксис: PAGE [израз] Предназначение: определяне на брой редове на страница от листинга (ако е въведен израз) и преминаване на нова страница. Забележки: Изразът трябва да бъде от абсолютен тип и не трябва да съдържа неопределени и/или външни символи. Директивата не влияе на работата, ако при стартиране на UniASM не е въведен параметър /l. 8. СВЪРЗВАЩ РЕДАКТОР ULINK В състава на операционната система UniDOS е включен свързващият редактор ULINK. Стартирането на свързващия редактор ULINK се осъществява чрез следната команда на UniDOS: ULINK [/[c][p]]<modules> където: c - опция за формиране (ако е възможно) на CMD-резултатен файл. Ако опцията е пропусната, то се формира PGM-резултатен файл. p - опция за изравняване на обектните модули на границата на страница. <modules> - списък на обектни модули или библиотеки, които трябва да бъдат свързани в изпълнима програма. Имената в списъка са без разширение. По премълчаване се приема разширение OBJ за обектен модул и LIB - за библиотеки. В резултат от работата на редактора се създава изпълнима програма с име, съвпадащо с името на модула, съдържащ директивата MAIN и с разширение на името CMD или PGM, в завиисмост от наличието или отсъствието на опцията /c. Всеки обектен модул се състои от сегмент на кода и разположен непосредствено след него сегмент на данни. Сегментът на данните може да включва САМО неинициализирани данни. За създаване на такъв сегмент се използва директивата SECT в началото на сегмента. В процеса на работа на редактора съответните сегменти на всички обектни модули се обединяват и се създават обединени сегменти на код и данни, отново разположени непосредствено един след друг. В обединените сегменти се включват САМО сегменти от обектните модули (на код и данни), към които има обръщение. Ако се генерира CMD-файл, програмата трябва да съдържа проверка за съществуване на достатъчна за разполагане на сегмента данни памет. При генериране на PGM-файл такова съответствие е гарантирано. PGM-файловете имат следния формат: адрес съдържание ------------------------------------- $00 (W) $A55A $02 (W) брой думи в таблицата на отместванията $04 (W) отместване на кода от началото на файла $06 (W) дължина на кода $08 (W) отместване на входната точка от началото на кода $0A (W) дължина на данните $0C-$0F 0 $10 начало на таблицата на отместванията от началото на кода По време на работата на свързващия редактор могат да бъдат получени следните ДИАГНОСТИЧНИ СЪОБЩЕНИЯ: 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 - грешка при запис на файл А. Приложение: КОМАНДИ НА МИКРОПРОЦЕСОРА СМ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. Приложение: ДИАГНОСТИЧНИ СЪОБЩЕНИЯ Грешките, откривани по време на асемблиране, се разделят на две групи: фатални, при които е невъзможно да бъде продължена транслацията; нефатални, след откриването на които транслацията може да продължи. Към съобщение за нефатална грешка се добавя и номера на програмния ред, където е установена грешката. Диагностичните съобщения са подредени в азбучен ред. След превода са посочени причините, ако не са очевидни. Фаталните грешки са отбелязани със знака "" след съобщението. Освен диагностични съобщения на асемблера е възможно извеждането и на диагностични съобщения на операционната система UniDOS. Те са описани във втората част на това приложение. При възникване на грешка, установявана от операционната система, асемблирането се прекратява. B.1. СОБСТВЕНИ НА UniASM СЪОБЩЕНИЯ BRANCH OUT OF RANGE - разклонение извън интервала - опит за относителна адресация извън интервала [.-130, +125]. BREAK - прекъсване - резултат от изпълнение на директива ERR. CONSTANT TOO LARGE - константа по-голяма от допустимото (65535). ILLEGAL CHAR IN LABEL - недопустим символ в етикета. ILLEGAL CHAR IN OPCODE - недопустим символ в кода на операцията - записаното в полето на операцията не е инструкция или директива ИЛИ в реда на директивата за даване на стойност "=" няма етикет. ILLEGAL CHAR IN OPERAND - недопустим символ в операнда - недопустим символ в полето на операнда ИЛИ отсъства скоба. INVALID ADDRESSING MODE - неправилен вид адресация - видът на адресацията не съответства на командата ИЛИ наличието/отсъствието на операнд не съответства на командата. INVALID EXPRESSION TYPE - неправилен тип на израз - използван израз от неправилен тип ИЛИ сумиране на относителни типове ИЛИ изваждане на относителен от абсолютен тип ИЛИ опит за използване на неразрешена операция над относителен тип. INVALID EXPRESSION SIZE - недопустима стойност на израза. INVALID OPCODE - недопустим код на операция. MEMORY FULL - достъпната за транслатора оперативна памет е запълнена. MISSING LABEL - липсва етикет. OPCODE NOT ALLOWED HERE - неразрешен код на операция - неправилно използване на директивата ORG или SECT. STACK FULL - стекът е заполнен - броят вложени скоби е над допустимото. SYMBOL ALREADY DEFINED - символът е вече дефиниран. SYMBOL TABLE FULL - препълване на таблицата на символите. UNEXPECTED END OF FIELD - неочакван край на поле - в края на полето липсва символ, операнд, знак и т.н., задължителен по синтаксис. UNDEFINED SYMBOL - неопределен символ - използване на повече от един неопределен символ в един израз ИЛИ неразрешено използване на неопределен или външен символ като параметър на директива ИЛИ използване на неопределен до края на програмата символ. B.2. СЪОБЩЕНИЯ НА UniDOS Access denied - забранен достъп - атрибутите на файла не позволяват достъп до него (запис и/или изтриване). Address failure - грешка в адресното поле на диска - вероятно дискетата е повредена. Attempt to remove the current directory - опит за изтриване на текущата директория. Bad command or file name - лоша команда (на UniDOS) или име на файл - най-вероятно - обръщение към незаписан на текущата дискета файл. Cannot execute .CMD file - CMD-файл не може да бъде изпълнен - най-вероятно - несъответствие по памет. Data failure - грешка в полето за данни на диска - вероятно дискетата е повредена. Directory exists - директория (с посоченото име) вече съществува. Directory not empty - директорията не е празна - вероятно при опит за изтриване. Disk full - дискът е пълен. Disk write protected - дискът е защитен срещу запис. Failure in .PGM file - грешка при стартиране на PGM-файл. FAT failure - грешка в таблицата на файловите атрибути - вероятно дискетата е повредена. File already open - файлът вече е отворен. File cannot be copied onto itself - файл не може да бъде копиран върху себе си. File creation failure - грешка при създаване на файл. File exists - файл с посоченото име съществува. File opening failure - грешка при отваряне на файл. File not found - файлът не е намерен. General failure - обща грешка - вероятно дискетата не е форматирана или е настъпила хардуерна грешка. Insufficient memory - недостатъчна памет. Invalid drive - неправилно указано дисково устройство. Invalid media type - неправилно указан тип на форматиране на дискетата. Invalid name - неправилно име. Invalid number of parameters - недопустим брой параметри. Invalid parameter - неправилен параметър. Invalid sector - неправилно посочен сектор на дискета. Not disk file - не е дисков файл. Not same device - не е същото устройство. Path not found - траекторията не намерена. Printer general failure - обща грешка при обръщение към принтера - вероятно принтерът не е включен. Printer out of paper - хартията на принтера е свършила. Printer timeout - грешка при работа с принтера. Root directory full - главната директория е запълнена до край. Too many open files - броят на едновременно отворените файлове е по-голям от допустимото.