РУКОВОДСТВО ПРОГРАММИСТА III.2. Диалоговый отладочный комплекс (продолжение) СОДЕРЖАНИЕ 2. АССЕМБЛЕР 2.1. Общие сведения и основные понятия 2.2. Структура программы 2.3. Определение и использование меток 2.4. Операнды 2.4.1. Числа 2.4.2. Символьные константы 2.4.3. Выражения 2.4.4. Указание типа адресации 2.5. Директивы Ассемблера 2.5.1. Формат директив 2.5.2. Организация исходной программы (CHN,INCLUDE) 2.5.3. Организация объектной программы (ORG,LOC) 2.5.4. Размещение объектной программы в памяти (OBJ) 2.5.5. Организация перемещаемых файлов (REL) 2.5.6. Определение меток (EQU) 2.5.7. Запись данных в программе 2.5.8. Задание внешней рабочей области (DSECT-DEND) 2.5.9. Объявление перекрестных ссылок (ENTRY-EXTRN) 2.5.10. Условное ассемблирование (DO-ELSE-FIN) 2.5.11. Выдача листинга ассемблирования 2.6. Ассемблирование 2.6.1. Имена исходных и порождаемых файлов Ассемблера 2.6.2. Запуск Ассемблера из командного режима 2.6.3. Запуск Ассемблера из ДОК 2.6.4. Управление листингом ассемблирования 2.7. Сводка отличий от Ассемблера ИКП 2.8. Использование памяти Ассемблером 2. АССЕМБЛЕР 2.1. Общие сведения и основные понятия Язык Ассемблера - язык низкого уровня. Данные, которыми он оперирует, - это ячейки памяти и хранящиеся в них числа небольшой разрядности. Программой на Ассемблере является последовательность ма- шинных команд, записанных в символическом виде. Команды языка соответствуют командам микропроцессора. Команда сос- тоит из мнемокода и не более чем одного операнда. Мнемокод определяет общую функцию команды независимо от типа адреса- ции, а операнд задает участвующие в ней данные одним из ти- пов адресации. Процесс трансляции с Ассемблера называется ассемблирова- нием. При ассемблировании каждая команда языка порождает одну машинную команду, а вся исходная программа - объектную (двоичную) программу. Поскольку объектная программа должна располагаться в конкретной области памяти, в исходной про- грамме должен быть задан ее начальный адрес, по которому при ассемблировании вычисляются абсолютные адреса размеще- ния всех команд. Для обозначения числовых данных и организации переходов используются символические метки. Все значения меток и до- пустимые операции над числами вычисляются при ассемблирова- нии и порождают в объектной программе числовые константы. В языке существует набор директив, позволяющих управлять ходом ассемблирования и размещением данных в объектной про- грамме. Ассемблирование ведется в два прохода: на первом опреде- ляются все адреса, на втором происходит фактическая генера- ция кода. 2.2. Структура программы Команды (а также директивы, которые ниже приравниваются к командам, если не оговаривается особо) записываются по одной в строке в следующем формате: [метка [:] ] [ {пробел} мнемокод [ {пробел} операнд]] коммент. Комментарием считается все, что остается в строке после обнаружения мнемокода и, если надо, операнда. Комментариями считаются также пустая строка и строка, начинающаяся с '*' и ';' . Метка может также располагаться на отдельной строке. Двоеточие к метке не относится и смысла не имеет. Мнемокоды команд состоят из трех прописных латинских букв. 2.3. Определение и использование меток Метка начинается с буквы и содержит строчные и заглавные русские и латинские буквы, цифры, точки и подчерки в любом порядке. Длина метки не ограничена, но значащими являются только первые 16 символов. Метка обозначает некоторое число и определяется тремя способами: - метка перед командой отождествляется с адресом размеще- ния этой команды; - метка перед директивой EQU отождествляется со значением операнда этой директивы; - метка после директивы EXTRN определяется с неопределен- ным значением, импортируемым из другого файла позже на этапе настройки внешних ссылок Компоновщиком. Повторные определения меток запрещены. Значение метки известно во всей программе независимо от места ее определения. Исключения: метки, участвующие в опе- рандах директив EQU, ORG, LOC, OBJ и DS должны быть опреде- лены ранее; то же касается меток, значения которых должны быть короткими: их определение должно быть раньше первого использования. Метки-адреса служат для программирования ссылок и пере- ходов в объектной программе. Если некоторая команда снабже- на меткой, то переход на нее задается указанием этой метки в команде перехода: JSR M ... M: LDA #0 ... BNE M При ассемблировании вычисляется реальный адрес помечен- ной команды, который и подставляется в адресную часть ко- манды перехода. В общем случае метки удобны для придания смысла исполь- зуемым константам, например: ШИРИНА EQU 32 ВЫСОТА EQU 4 LDA #ШИРИНА*ВЫСОТА 2.4. Операнды 2.4.1. Числа Числа в Ассемблере служат для записи адресов и содержи- мого ячеек памяти и поэтому, в зависимости от смысла, имеют различные диапазоны представления: - однобайтовые (короткие числа) от 0 до 255 - непосред- ственные операнды и адреса ячеек 0-й страницы; - двухбайтовые (длинные числа) от 0 до 65535 - произволь- ные адреса памяти. Короткие числа употребимы везде, где требуются длинные, но приводятся к двухбайтовому виду. Верно и обратное, но при этом старший байт отбрасывается. Особые префиксы позволяют задавать числа в 4-х системах счисления: - десятичной: 123 , 62236 (без префикса); - шестнадцатеричной: $7B , $F31C ; - восьмеричной: @173 , @171434 ; - двоичной: :01111011 , :1111001100011100 . 2.4.2. Символьные константы Символьная константа - это произвольный символ, перед которым стоит апостроф ('). Можно ставить апостроф и после символа. Примеры: 'A '5 '#' '' (сам апостроф) Символьная константа преобразуется в короткое число: код указанного символа. В директивах ASC и DCI используется текстовая константа: последовательность символов, заключенная в произвольный ог- раничитель, не встречающийся в тексте: .ЭTO TEKCT. "ПPИBET" =TEKCT "ПPИBET"= 2.4.3. Выражения Выражение имеет вид: [ < ] число { знак_операции число } > знак_операции: + - * / ! & % Пробелы в записи выражения недопустимы. Вместо чисел могут употребляться метки, символьные кон- станты и символ '*' , означающий адрес размещения текущей команды. Логические операции И '&', ИЛИ '!' и Исключающее ИЛИ '%' выполняются поразрядно. Арифметические операции сложения '+', вычитания '-', ум- ножения '*' и деления нацело '/' выполняются по модулю 65536 ($10000): 65500+200=164 $1234-$1237=$FFFD . Унарные операции '<' и '>' переводят в короткое число, соответственно, старший или младший байт длинного числа в принятом понимании (номер страницы и номер байта в страни- це): >$ABCD - это $CD , <$ABCD - это $AB . Все операции имеют равный приоритет, выражения вычисля- ются слева направо, скобки недопустимы. Операции '>' и '<' вычисляются последними. Правила определения типа числа в выражении: - операнды при непосредственной и косвенной адресации мо- гут быть заданы короткими числами, но окончательный резуль- тат автоматически приводится к короткому числу отбрасывани- ем старшего байта: LDA (0-1),Y ;=$FF LDA #$1234 ;=$34 - в других случаях тип адресации (абсолютный или 0-страни- чный) определяется по типу первого числа в выражении: LDA 0-1 ($FF!) и LDA $20,X - это 0-страничная, LDA $FFFF+1 LDA $100-1 - это абсолютная. Примеры выражений: 10*$A+7 ; = 107=$6B 10*$A+7/2 ; = 107/2=53=$35 <@17*@30 ; = 15*24/256=1 :10110110%:10110111 ; = :00000001 >$3FFF+1 ; = 0 <$3F0F+1 ; = $3F, а не $40 *+2 ; = тек.адрес+2 5*7+* ; = <тек адрес+35 Запись адреса ADR в две последовательные ячейки: LDA #>ADR STA ADRES LDA #ADRES LDA (ADRES,X)+1 ASL A CMP A LSR LDA 10+>$1000 STA (LOC+2),Y STA (LOC)+2,Y ADC COMMON-1,X ADC COMMON,X-1 CMP WORK STA ADR+#8 2.5. Директивы Ассемблера 2.5.1. Формат директив Директивы имеют тот же формат записи, что и команды (мнемокод и операнд), и служат указаниями Ассемблеру выпол- нить те или иные действия с исходной или объектной програм- мой, листингом и т.д. Список директив: ASC DEND DW FIN REP CHR DFB ELSE LST SBTL CHN DO ENTRY MSB SKIP DCI DS EXTRN PAGE OBJ DDB DSECT EQU REL ORG новые директивы, добавленные в версии ОС "Спрайт": LOC IF ENDIF INCLUDE 2.5.2. Организация исходной программы (CHN,INCLUDE) Исходная программа может располагаться в одном текстовом файле или в нескольких. Связать в список для ассемблирова- ния несколько файлов позволяет директива: CHN имя следующего файла которую следует ставить в последней строке каждого файла, кроме последнего. Другая директива: INCLUDE имя включаемого файла позволяет вставить текст указанного файла в текущее место текущего файла - с продолжением ассемблирования последнего по исчерпании первого. При этом содержимое всех связанных файлов рассмативается как единая исходная программа. Ограничения на порядок ассемблирования связанных файлов см. в 2.6. 2.5.3. Организация объектной программы (ORG,LOC) Директива: ORG адрес задает новую объектную программу, т.е.: - записывает на диск предыдущую программу, если она была (под каким именем - см. в 2.6.1); - устанавливает адрес размещения объектной программы (т.е. адрес первой команды). Директива: LOC адрес меняет только адрес размещения последующего фрагмента; но при этом он продолжает записываться в тот же объектный файл; при загрузке такого файла последующий участок окажется "не на своем" месте: для правильного исполнения его надо будет переместить по "своему" адресу. Если директиве LOC не прдшествовала ни одна директива ORG, та работает в точности как ORG. Xотя бы одна директива организации объектной программы обязательна, иначе объектная программа не порождается. Размер объектной программы ограничен величиной $FFFF. 2.5.4. Размещение объектной программы в памяти (OBJ) OBJ адрес Директива размещает последующую часть объектной програм- мы с указанного адреса в оперативной памяти. Размещение происходит по ходу ассемблирования и не влияет на объектную программу, записываемую в файл на диск. Возможны коллизии при размещении объектной программы не на "своем" месте (заданном в ORG): абсолютные адреса всех ячеек и точек перехода остаются прежними, в то время как программа находится в другом месте. Пользуясь размещением, следует учитывать использование оперативной памяти в системе (в частности, Ассемблером). 2.5.5. Организация перемещаемых файлов (REL) REL Директива включает генерацию объектной программы в пере- мещаемом формате. Такая программа не может быть исполнена непосредственно после загрузки в память и требует абсолют- ной настройки Компоновщиком, возможно, с одновременной ком- поновкой с другими программами. 2.5.6. Определение меток (EQU) метка EQU выражение Директива служит для обозначения числовых констант мет- ками, что облегчает чтение программы и ее модификацию. При- мер: ЭКРАН EQU $1000 ВЕРХ EQU 5 ВЫСОТА EQU 20 ЛЕВЫЙ EQU 2 ШИРИНА EQU 28 ПРАВЫЙ EQU ЛЕВЫЙ+ШИРИНА-1 НИЗ EQU ВЕРХ+ВЫСОТА СМЕЩ EQU ВЕРХ*ШИРИНА ОКНО EQU ЭКРАН+СМЕЩ Изменение этих констант приведет к изменению параметров окна экрана во всей программе. Выражение в правой части вычисляется при первом проходе ассемблирования, поэтому все метки, использумые в ней, дол- жны быть определены ранее. Все определения удобно сосредоточить в начале программы, разбив на смысловые группы. 2.5.7. Запись данных в программе Все последующие директивы записывают в объектную про- грамму последовательность байтов, начиная с текущего адреса размещения: DFB M1,...,Mn - запись серии коротких чисел по одному в байте; DW A1,...,An - запись серии длинных чисел в виде адресов (>A,A); (Примечание: в данной версии DW и DDB имеют один операнд) ASC XтекстX - запись ASCII-кодов символов текста по од- ному в байте; X - любой символ, которого нет в тексте; DCI XтекстX - то же, но у всех символов, кроме последне- го, старший бит будет сброшен (такое пред- ставление удобно для маркировки конца тек- ста); DS X - запись указанного числа (длинного) нулевых байтов; используется для резервирования рабочих областей в теле объектной программы. Bспомогательная команда MSB ON или MSB OFF переключает режим установки/сброса старшего бита (1 и 0, соответственно) при кодировке символьных констант и текстов в директивах ASC и DCI. По умолчанию установлено MSB ON. 2.5.8. Задание внешней рабочей области (DSECT-DEND) DSECT ... DEND Директивы ограничивают фрагмент программы, не порождаю- щий объектного кода. Таким образом удобно ссылаться на ра- бочие ячейки и таблицы в других программах, лежащие в фик- сированных адресах. Например: DSECT ORG $2000 TAB EQU * ; = 2000 На эти метки возможны ссылки T.TREK DS 1 ; = 2000 из данной программы T.SECT DS 1 ; = 2001 T.BUFF DS 2 ; = 2002 DEND 2.5.9. Объявление перекрестных ссылок (ENTRY-EXTRN) ENTRY метка EXTRN метка Позволяют задавать перекрестные ссылки между различными программами, если используется Компоновщик. ENTRY задается в программе, содержащей определяемую мет- ку, EXTRN - в использующей эту метку программе. При этом в перемещаемые файлы обеих объектных программ заносится имя метки, чтобы настроить связь при компоновке. Директива EXTRN попутно объявляет данную метку в исход- ной программе с неопределенным (реально, нулевым) значением. Другой способ настройки перекрестных ссылок - задавать адреса меток, внешних по отношению к данной программе, их абсолютными адресами, используя директиву EQU. 2.5.10. Условное ассемблирование (DO-ELSE-FIN) DO выражение или DO выражение DO <-> IF ... ... ELSE FIN ... FIN FIN <-> ENDIF Если значение выражения равно 0, то участок программы между DO и FIN (DO и ELSE) игнорируется при ассемблировании. В первом случае вместо него анализируется участок ELSE-FIN, который игнорируется, если выражение ненулевое. Директивы IF и ENDIF являются более традиционной формой записи DO и FIN, которые оставлены для совместимости. 2.5.11. Выдача листинга ассемблирования Включать и выключать выдачу листинга можно или непосред- ственно с клавиатуры во время ассемблирования или с помощью директив LST ON и LST OFF . Директива LST REST восстанавливает тот режим листинга, который был установлен до предыдущего LST ON/OFF. Следующие директивы служат для оформления листинга: SBTL XтекстX - включает постраничную распечатку листинга с указанным заголовком страниц. Размер стра- ницы задается во входной строке или особой директивой (пока ее нет). Текст не обязате- лен. PAGE - заканчивает текущую страницу прогоном нуж- ного числа пустых строк или выдачей 'Упр-L'. CHR символ - задает символ, используемый в директиве REP; REP число - вставляет в листинг строку-разделитель, со- стоящую из указанного числа одинаковых сим- волов (если не был задан в CHR, то '*'); SKP число - выдает указанное число пустых строк. Листинг может быть организован постранично. Для этого директивой ... или входным параметром устанавливаются раз- мер логической страницы - число строк, через которые по ко- манде SBTL выдается шапка нового листа, - и размер физичес- кой страницы - число строк, через которое принтер делает межстраничный пропуск (если делает). 2.6. Ассемблирование 2.6.1. Имена исходных и порождаемых файлов Ассемблера Ассемблер воспринимает и генерирует файлы только со стандартными расширениями имен: '.ASM' - для исходных текстовых файлов; '.PRG' - для объектных программных файлов; '.REL' - для объектных перемещаемых файлов; '.LST' - для выходных файлов листинга; '.DBG' - для файлов с отладочной информацией для Отладчика Debugger. Расширения файлов можно не указывать: они образуются из заданного имени исходного файла добавлением или заменой нужного расширения. Если исходным текстом порождаются несколько объектных файлов (директива ORG встречается более 1 раза), то имена 2-го и последующих объектных файлов образуются из имени первого приписыванием порядкового номера перед расширением. Например, 3 объектных программы, порожденные из исходного файла с именем 'ПРИМЕР.ASM' будут иметь имена 'ПРИМЕР.CMD', 'ПРИМЕР1.CMD' и 'ПРИМЕР2.CMD'. Если имя исходного, объектного или листингового файла указать с каким-либо расширением, то оно не заменяется. 2.6.2. Запуск Ассемблера из командного режима Автономный Ассемблер находится в файле 'ASM.PRG' и за- пускается обычным образом. Имена файлов и другие параметры задаются во входной строке; подсказка по форме их задания выдается на экран при запуске Ассемблера с пустой входной строкой или с ключом /H : Запуск: ASM[/ключи] srс {оbj} {lst} srс - имя исходного файла оbj - имя объектного файла lst - имя файла листинга Общие ключи: D - генерировать DBG-файл H - эта подсказка N - не генерировать код R - генерировать REL-файл Ключи листинга: L - в файл P[=<формат>] - на принтер S - на экран W - постраничная печать 2.6.3. Запуск Ассемблера из ДОК Запуск Ассемблера из ДОК осуществляется через меню под- систем вызовом функции АССЕМБЛЕР. При этом выдается допол- нительное меню запросов параметров ассемблирования: >> НАЧАТЬ АССЕМБЛИРОВАНИЕ ИЗ ФАЙЛА: В памяти - исходный файл В ФАЙЛ: XXX.PRG - объектный файл ЛИСТИНГ: нет - файл листинга НА ЭКРАН: да - листинг на экран DBG-ФАЙЛ: нет - отладочный файл XXX.DBG Для изменения параметров требуется "исполнить" соответ- ствующие альтернативы: это приведет к запросу имен (в пос- ледних двух строках - к смене "да" на "нет" и наоборот). При вводе пустых строк исходный файл берется "в памяти", т.е. из текущего буфера редактирования, а объектный файл и файл листинга отменяются ("нет"). При смене исходного файла заново переопределяются имена объектного (заменой расшире- ния исходного имени на '.PRG') и файла-листинга (на '.LST') - если последний не отменен. По умолчанию в качестве имени исходного файла берется имя текущего текста в буфере Редак- тора. Расширения при наборе можно опускать: они устанавливают- ся автоматически так же, как при автономном запуске. При ассемблировании файла из памяти его текст сохраняет- ся в буфере Редактора. Ассемблирование нескольких файлов, связанных директивами CHN и INCLUDE возможно только с дис- ка. Ассемблирование больших файлов ведется по частям с под- загрузкой в память. По окончании ассемблирования буфер со- держит последний файл либо очищается, если этот файл не по- мещается в память целиком. 2.6.4. Управление листингом ассемблирования В процессе ассемблирования его листинг может выдаваться на экран, на принтер, и в файл - в зависимости от установ- ленных входных параметров в меню или входной строке. Генерация листинга включается и отменяется директивой LST ON/OFF в исходном тексте - независимо от того, куда он будет выдаваться. Включить и выключить вывод листинга на экран позволяют клавиши ф2 и ф3. Прекращение ассемблирования - ф1. Приоста- нов и продолжение вывода листинга - пробел. Строка листинга имеет вид: адрес_размещения: код номер_строки текст_строки или содержит сообщение об ошибке. Например: 1C72: 20 13 18 92 METKA JSR KEYIN ;ЖДEM ПC 1C75: C9 8D 93 CMP #RETURN 1C77: D0 F9 94 BNE METKA *** Неизвестная метка в строке 95 1C79: 4C 00 00 95 JMP XXXX Строка, содержащая ошибку, может порождать неверный код. По окончании ассемблирования выдается сводный список ошибок, последняя объектная программа записывается на диск независимо от ошибок, и выдаются две сводные таблицы меток и их значений (одна упорядочена по ASCII-коду, другая - по возрастанию адресов), например: 1C4A ABS 76 AREASIZE ? 0986 C.TABLE 32 INVFLG N 1C72 METKA * 0000 XXXX Добавочными знаками отмечаются: ? - метки, на которые нет ссылок; * - неопределенные метки; X - EXTRN-метки; N - ENTRY-метки; R - перемещаемые метки. 2.7. Сводка отличий от Ассемблера ИКП 1. Существует автономная версия с запуском из командного режима и управлением через входную строку. 2. Изменен интерфейс в составе ДОК. 3. Ускорен процесс ассемблирования. 4. Изменены и расширены состав и формат выходных файлов. 5. Добавлены директивы IF, ENDIF, DBG, LOC. 6. Сняты ограничения на размеры исходных и объектных файлов (частичная дозагрузка и запись). 7. Возможен вывод листинга в файл. 8. Длина значимой части метки ограничена 16-ю символами. 9. Допустима запись 'ROL' вместо 'ROL A'. 10. Директива 'ORG' всегда порождает новый объектный файл. 11. Порождаются DBG-файлы с информацией о метках. 12. В листинге изменен формат таблицы меток. 13. Переопределены клавиши управления листингом: ф1,ф2,ф3. 14. Возможно указание полного пути для исходных файлов. 15. Введены числовые парметры, передаваемые из командной строки. 16. К переключателям 'ON/OFF' добавлен 'REST', по которому восстанавливается предыдущее значение. 2.8. Использование памяти Ассемблером Информация об используемой Ассемблером памяти может быть полезна при работе в ДОК: D000-EEFF (ROM2-D0) - рабочий модуль Ассемблера; 8000-BFFF (RAM2) - рабочий буфер таблиц меток и перемещения; 1800-1BFF (авт.), 7E00-7FFF (в ДОК) - входные параметры и рабочая область; 0060-00A1 - рабочие ячейки 0040-007F - входные параметры (из входной строки Командера);