Запись текста программы
Исходный текст программы представляет собой последовательность операторов языка, сгруппированных в сегменты и оформленных в виде файла.
Оператор (рис. 4.2) — это базовая конструкция языка программирования, определяющая действия в программе. В языке программирования ASM-51 в одной строке может быть записан только один оператор. Максимальный размер строки — 255 символов. Признаком конца оператора является символ "возврат каретки". Оператор состоит из трех полей: поле метки, поле операции и поле комментария
Рис. 4.2. Пример оператора, записанного на языке программирования ASM-51
Поле метки используется для записи меток (рис. 4.3). Метки используются для организации условных и безусловных переходов, а также для объявления переменных и констант. Признаком конца поля метки является символ "двоеточие" (:).Однако язык программирования ASM-51, в виде исключения, допускает использовать символы интервала как признак конца поля метки.
Рис. 4.3. Пример применения метки и комментария
Поле операции используется для записи директивы языка или инструкции микроконтроллера, которые состоят из мнемонического обозначения команды микроконтроллера и одного или нескольких операндов. В качестве операндов могут использоваться адреса ячеек памяти, обозначения регистров или метки операторов. Операнды отделяются друг от друга запятыми.
Поле комментария начинается с символа "точка с запятой" (;). Это необязательное поле используется для записи пояснений к программе.
Алфавит языка.
Символы исходной программы представляют собой подмножество таблиц символов ASCII для DOS и ANSI для WINDOWS. В исходном тексте программы допустимо использование следующих символов:
-символы интервала ("пробел" и " табуляция");
-буквы (от “A” до “Z”, от “a” до “ z”);
-знаки;
-цифры (0, 1, 2, 3, 4, 5, 6, 7, 8, 9).
Идентификаторы.
Идентификатор это символическое обозначение объекта программы. В качестве идентификатора может быть использована любая последовательность букв и цифр. При этом в качестве буквы может быть использована любая буква латинского алфавита, а также вопросительный знак (?) и знак "нижнее подчеркивание" (_). Идентификатор может начинаться только с буквы. Это позволяет отличать его от числа. В идентификаторах, язык программирования ASM-51 различает буквы верхнего и нижнего регистров. Количество символов в идентификаторе ограничено длиной строки (255 символов). Транслятор различает идентификаторы по первым 31 символам.
Примеры идентификаторов: ADD5, FFFFH, ?, ALFA_1.
В языке программирования ASM-51 имеются три категории идентификаторов.
1. Ключевое слово является определяющей частью оператора языка ассемблера. Значения ключевых слов языка ассемблера АSМ-51 не могут быть изменены или переопределены в программном модуле каким-либо образом. Ключевому слову не может быть назначено имя- синоним. Ключевые слова могут быть написаны буквами как верхнего, так и нижнего регистров.
В языке АSМ-51 имеются следующие категории ключевых слов: инструкции, директивы, вспомогательные слова, операции.
Инструкции по форме записи совпадают с мнемоническими обозначениями команд микроконтроллеров семейства MCS-51 и совместно с операндами, составляют команды микроконтроллера.
Директивы совместно с вспомогательными словами определяют действия в программе, которые должны быть выполнены ассемблером в процессе преобразования исходного текста программы в объектный код. В языке программирования ASM51 используются:
Директивы:
BIT, BSEG, CODE, CSEG, DATA, DB, DBIT, DS, DSEG, DW, END, EQU, EXTRN, IDATA, ISEG, NAME, ORG, PUBLIC, RSEG, SEGMENT, SET, USING, XDATA, XSEG.
Вспомогательные слова:
AT, BIT, BITADDRESSABLE, CODE, DATA, IDATA, INBLOCK, INPAGE, NUMBER, PAGE, UNIT, XDATA.
Операции выполняются ассемблером в процессе вычисления выражений на этапе трансляции исходного текста программы для определения конкретного числа, которое используется в команде. Перечень операций, использующихся языком программирования ASM-51: AND, EQ, GE, GT, HIGH, LE, LOW, LT, MOD, NE, NOT, OR, SHL, SHR, XOR.
2. Встроенные имена (табл. 4.1) — присвоены адресам регистров специальных функций, адресам флагов специальных функций AR0-AR7, рабочим регистрам R0-R7 текущего банка регистров, а также аккумулятору A и флагу переноса C.
Встроенные имена языка ASM-51
Таблица 4.1.
Имя | Регистр |
A | аккумулятор |
R0-R7 | 8-разрядный рабочий регистр текущего банка рабочих регистров |
AR0-AR7 | адреса 8-разрядных рабочих регистров текущего банка рабочих регистров |
DPTR | 16-разрядный регистр-указатель данных |
PC | 16-разрядный счетчик команд |
С | флаг переноса |
AB | регистровая пара, состоящая из аккумулятора A (старшая часть) и регистра B (младшая часть) |
3. Определяемые имена - имена объявляются пользователем. В языке программирования ASM-51 имеются следующие категории определяемых идентификаторов:
метки, внутренние и внешние переменные адресного типа, внутренние и внешние переменные числового типа, имена сегментов, названия программных модулей.
Числа
В языке программирования ASM-51 используются целые беззнаковые числа, представленные в двоичной, восьмеричной, десятичной и шестнадцатеричной формах записи. Для определения основания системы счисления используется суффикс (буква, следующая за числом):
· B-двоичное число (разрешённые цифры 0,1);
· Q\O- восьмеричное число (разрешённые цифры 0, 1, 2, 3, 4, 5, 6, 7);
· D -десятичное число (разрешённые цифры 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
· H-шестнадцатеричное число (разрешённые цифры 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , A, B, C, D, E, F).
Для десятичного числа суффикс может отсутствовать. Количество символов в числе ограничено размером строки, однако значение числа определяется по модулю 216 (т.е. диапазон значений числа находится в пределах от 0 до 65535).
Число всегда начинается с цифры. Это необходимо для того, чтобы отличать шестнадцатеричное число от идентификатора.
Часто бывает удобно выполнить некоторые вычисления для того, чтобы получить число. Язык программирования ASM-51 позволяет выполнять беззнаковые операции над числами (табл. 4.2).
Операции языка ASM-51
Таблица 4.2.
Арифметические операции | |
+ | суммирование |
- | вычитание |
* | умножение |
/ | деление |
mod | вычисление остатка от целочисленного деления |
Логические операции | |
not | побитовая инверсия операнда |
and | логическое "и" |
or | логическое "или" |
xor | "исключающее или" (суммирование по модулю два) |
Операции преобразования данных | |
high | выделение старшего байта 16-разрядного числа |
low | выделение младшего байта 16-разрядного числа |
Рис. 4.4. Пример использования выражений для определения числовой константы:
В языке программирования ASМ-51 также определена одноместная операция '-'. Для нее требуется один операнд, которому она предшествует. Для изменения порядка выполнения операций можно воспользоваться скобками.
Часто число используется для представления символов. В этом случае для определения числа можно воспользоваться литеральной константой. Литеральная константа заключается в апострофы: mov SBUF, #’Б’.
Директивы
Язык программирования ассемблер всегда включает в себя машинные коды микроконтроллера, но этим не ограничивается набор команд этого языка. Дело в том, что нужно уметь управлять самим процессом трансляции программы. Рассмотрим некоторые из директив.
Первое, что неудобно при использовании только машинных команд - это необходимость помнить, какие данные в какой ячейке памяти находятся. При чтении программы трудно отличить константы от переменных, ведь они отличаются в командах только видом адресации. Преодолеть эту трудность можно при помощи идентификаторов. Можно назначить какой либо ячейке памяти идентификатор, и тем самым работать с этим идентификатором как с переменной.
Директива equ (рис. 4.5) позволяет назначать имена переменных и констант. Теперь можно назначить переменной адрес в одном месте и пользоваться идентификатором переменной во всей программе. Правда за использование идентификатора именно в качестве переменной отвечает программист. Тем не менее, если в процессе написания программы потребуется изменить адрес переменной, это можно сделать в одном месте программы, а не просматривать всю программу, разбираясь является ли в данной конкретной команде число 10 константой, адресом ячейки ли количеством повторов в цикле. Все необходимые изменения сделает сам транслятор.
Рис. 4.5. Пример назначения переменных при помощи директивы equ.
Один раз назначенный идентификатор уже не может быть изменён в дальнейшем и при повторной попытке назначения точно такого же имени идентификатора будет выдано сообщение об ошибке.
Директива set. Если требуется в различных местах программы назначать одному и тому же идентификатору различные числа, то нужно пользоваться директивой set. Использование этой директивы полностью идентично использованию директивы equ.
Директива db (Рис. 4-6) используется для занесения в память программ однобайтных констант. В директиве db можно задавать сразу несколько констант, разделённых запятыми. Можно одновременно использовать все системы счисления.
Рис. 4.6. Пример назначения констант при помощи директивы db.
Обычно имеет смысл снабдить каждую константу комментарием, как это сделано в предыдущем примере. Так программа становится более понятной и легче искать допущенную ошибку.
Эта же директива позволяет легко записывать надписи, которые в дальнейшем потребуется высвечивать на встроенном дисплее или экране дисплея универсального компьютера, подключённого к разрабатываемому устройству через какой либо интерфейс.
Директива dw позволяет заносить в память программ двухбайтные числа. В этой директиве, как и в директиве db числа можно заносить через запятую.
При трансляции исходного текста программ предполагается, что первая команда расположена по нулевому адресу. Адрес последующих команд зависит от длины и количества предыдущих команд.
Иногда требуется расположить команду по определённому адресу. Наиболее часто это требуется при использовании прерываний, когда первая команда программы-обработчика прерываний должна быть расположена точно на векторе прерывания. Это можно сделать используя команду nop для заполнения промежутков между векторами прерывания, но лучше воспользоваться директивой ORG (рис. 4.7). Директива org предназначена для записи в счетчик адреса сегмента значения своего операнда. То есть при помощи этой директивы можно разместить команду (или данные) в памяти микроконтроллера по любому адресу.
Рис. 4.7. Пример использования директивы ORG для размещения подпрограмм обработки прерываний на векторах прерываний:
Директива using При использовании прерываний критичным является время, занимаемое программой, обработчиком прерываний. Это время можно значительно сократить, выделив для обработки прерываний отдельный банк регистров. Выделить отдельный банк регистров можно при помощи директивы USING. Номер банка используемых регистров указывается в директиве в качестве операнда.
Директива CALL. В системе команд микроконтроллера MCS-51 используется три команды безусловного перехода. Выбор конкретной команды зависит от расположения ее в памяти программ, однако программист обычно этого не знает. В результате во избежание ошибок приходится использовать самую длинную команду LJMP. Это приводит к более длинным программам и к дополнительной нагрузке на редактор связей. Транслятор сам может подобрать наилучший вариант команды безусловного перехода. Для этого вместо команды микроконтроллера следует использовать директиву call.
Остальные директивы предназначены для управления сегментами, и поэтому будут рассмотрены позднее.