4.2. Компилятор ассемблера микроконтроллеров AVR
Компилятор транслирует исходные коды с языка ассемблера в объект ный код. Полученный объектный код можно использовать в симуляторе AVR Studio. Компилятор также генерирует код, который может быть непо средственно записан в память микроконтроллера. Текст программы для компилятора должен строго соответствовать рассмотренным ниже синтак сическим правилам. Приведенные ранее в примерах фрагменты программ соответствуют этим правилам.
Компилятор работает с исходными файлами, содержащими в каждой строке метку, команду или директиву и комментарии. Строка не должна быть длиннее 120 символов. Любая строка может начинаться с метки, ко торая является набором символов, заканчивающимся двоеточием. Метки используются для указания места, в которое передаётся управление при пе реходах, а также для задания имён переменных. Комментарий имеет сле дующую форму:
;[Текст]
Текст после точки с запятой и до конца строки игнорируется компилято ром, эти комментарии обычно объясняют назначение и смысл выполняе мых операций, что существенно облегчает понимание реализуемых в про грамме алгоритмов работы.
Входная строка может иметь одну из четырёх форм (позиции в квадрат
ных скобках необязательны): |
|
|
|
[метка:] |
директива |
[операнды] |
[/Комментарий] |
[метка:] |
команда |
[операнды] |
[;Комментарий] |
;Комментарий |
|
|
|
Пустая строка
Перечень команд с допустимыми операндами (регистры, адреса, кон станты или метки) приведен выше. Каждая команда преобразуется ком
пилятором в соответствующий код операции программы микрокон троллера. Мнемоника команд и операндов должна строго соответствовать указанной в описаниях. Текст в приведенных ранее примерах использова ния команд составлен в соответствии с требованиями компилятора. Регистр для символов (прописные, строчные) и пробелы для компилятора значения не имеют.
Директивы не транслируются непосредственно в код. Они исполь зуются компилятором для указания положения в программной памяти, оп ределения макросов, инициализации памяти и т.д. Признаком директивы служит точка перед текстом директивы, например: .CSEG. Ниже дано описание директив компилятора, которые в дальнейшем будут применяться в текстах программ.
Директивы .CSEG, .DSEG, .ESEG указывают соответственно на память программ, память данных, EEPROM (EEPROM), к которым относится дальнейший текст программы (по умолчанию тексты программ предназна90
чены для памяти .CSEG). Эти директивы необходимы в связи с использо ванием трех раздельных адресных пространств в памяти микроконтролле ров AVR. Вместе с директивой .ORG k определяют конкретные физиче ские адреса ячеек памяти для хранения кодов программы:
.CSEG |
|
|
.ORG $120 |
|
проверка старших битов АЦП |
more: cpi |
г19, $00 |
|
brne |
repADl |
; перейти, если не равно |
mov |
rl7,rl8 |
;сдвиг влево для проверки бита 7 |
Mr 17 |
||
brcs |
repADl |
;перейти, если бит 7 неравен 0 |
.ORG $090 repADl: nop
В приведенном примере коды будут записаны в памяти программ (.CSEG); метка more и код этой строки записываются по адресу $120, последующие коды - в следующие по порядку ячейки памяти. Вторая директива .ORG $090 указывает, что код, соответствующий метке repADl, компилятор должен разместить по адресу $090.
Директивы .DB (определить байты), .DW (определить слова) позволяют записать в память программ или EEPROM массивы однобайтных или двух байтовых констант соответственно. Могут использоваться метки для ссы лок на адреса памяти, по которым директивы записывают константы. Вме сте с директивой ORG позволяют задавать конкретные физические адреса памяти для хранения констант. Директивы DB и DW должны содержать список констант, разделенных запятыми:
.ESEG
const!: . DB 02, 255, ObOlOWlOl, -128, Охаа
.CSEG
.ORG $380
led:. DW $063/, $4f5b, 6d66, a77d, $0000
91
Массив однобайтовых констант (DB) записан в EEPROM, адреса EEPROM определяются компилятором, адрес первой константы массива (02) соот ветствует метке const 1. Массив двухбайтовых констант (DW) записан в па мять программ, адрес первой константы ($063f) соответствует метке led и определяется директивой .ORG $380.
Директива .INCLUDE "имя файла" (присоединить файл) позволяет включить в текст программы другие файлы. Например: .INCLUDE "8535def.inc" включает в текст программы файл определения стандартных символических имен регистров и переменных. Этот файл позволяет ис пользовать в текстах программ в качестве операндов символические имена, определяемый директивами компилятора DEF, EQU, SET.
Директивы .DEF (установить регистру имя), .EQU (установить имени постоянное значение), .SET (установить имени переменное значение) по зволяют установить для компилятора соответствие символьных имен и операндов в текстах программ. Директива .EQU указывает для имени зна чение, которое не может быть изменено, а директива .SET допускает изме нение этого значения другой директивой. Значения символических имен могут задаваться в виде числовых констант или выражений. Более подроб но с правилами записи выражений можно ознакомиться в документации фирмы ATMEL. Примеры применения директив:
.EQU MCUCR=$35 |
|
установить постоянное значение |
|
.EQU MCUSR:=S34 ; |
для переменной суказанным |
||
.EQU PORF =0 |
; |
символическим именем |
|
.DEF |
XL—r26 |
установить регистру R26 имя XL |
|
.DEF |
XH-r27 |
установить регистру R27 имяХН |
|
Первая директива в данном примере назначает переменной с именем MCUCR постоянное значение шестнадцатеричного числа $35 (в десятич ном формате 53), в командах, где требуется указать это значение операнда, можно приводить либо численное значение ($35), либо символическое имя (MCUCR). Например, команды out $35, г26 и out MCUCR, XL абсолютно эквивалентны; в первом варианте для операндов используются их физиче ские значения, во втором варианте - их символические имена. Как отмеча лось ранее, использование символических имен существенно упрощает мнемонику команд, при подготовке программ гораздо легче работать с именами операндов, чем запоминать большое количество адресов, число вых констант и т.п. Целесообразно также использовать стандартные симво92
лические имена, назначаемые специальными файлами для каждой модели микроконтроллера.
Полезными при подготовке текстов программ могут быть директивы
.NOLIST (исключить из листинга), .LIST (включить в листинг). Эти ди рективы не содержат операндов и позволяют исключить из листинга про граммы текст, находящийся ниже директивы .NOLIST и выше директивы
.LIST. Например, целесообразно исключать из листинга программы файл определения стандартных символических имен 8535def.inc, так как он не содержит исполняемых кодов и занимает в листинге объем нескольких страниц текста.
Компилятор позволяет использовать в тексте программ выражения, ко торые могут состоять из операндов, операторов и функций. Формат выра жений - 4 байта, т.е. они могут содержать значения переменных, уклады вающихся в 4-х байтовый диапазон.
Операндами в выражениях могут быть числа; символические имена, оп ределенные директивами .SET и .EQU; метки программы (каждая метка в тексте программы соответствует определенному числу - физическому ад ресу памяти); PC - текущее состояние программного счетчика.
Над операндами в выражениях можно выполнять различные математи ческие операции, задаваемые операторами. Операторы имеют стандартные для компьютерных приложений обозначения:
•арифметические операторы: + , - , * , / ;
• |
операторы сдвига: влево « |
, вправо » |
; |
|
||
• |
логические операторы: & , |
&& , |
|, |
||, |
! , |
Л ; |
• |
операторы отношений: = , |
!= , |
<, |
<= , |
> , |
>= . |
Элементы выражений (операнды с операторами) могут быть заключены в круглые скобки, как и в любых математических преобразованиях.
Выражения могут быть аргументами следующих функций:
•LOW(выpaжeниe) - младший байт выражения,
•НЮН(выражение) - второй байт выражения,
•ВУТЕ2(выражение) то же что и функция HIGH,
•ВYTE3(выражение) - третий байт выражения,
•ВУТЕ4(выражение) - четвёртый байт выражения,
•L\¥ЮЗ(выражение) - биты 0-15 выражения,
•Н\^1Ш(выражение) - биты 16-31 выражения,
•РАСЕ(выражение) - биты 16-21 выражения,
•ЕХР2(выражение) - 2 в степени (выражение),
•ЬОС2(выражение) - целая часть 1о§2(выражение).
93
Примеры выражений: |
|
|
|
||
Idi |
rl6, LOW(RAMEND) |
;RAMEND=0x025f, LOW(RAMEND)~0x5f |
|||
out |
SPL, rl6 |
инициализация |
младшего байта указателя |
стека |
|
Idi |
rl6, HIGH(RAMEND) |
; HIGH(RAMEND) =0x02 |
|
||
out |
SPH, r!6 |
; инициализация старшего байта указателя |
стека |
||
Mi |
rl6, (1«OCIE1A)\(1«TOIEO) |
загрузить в г16 константу |
|||
|
;в виде выражения, определяющего разрешения прерываний |
||||
|
;таймеров 0 и 1 с использованием символических имен флагов |
||||
|
;этих прерываний, |
|
|
|
|
out |
TIMSK, г!6 |
;передать константу из г16 в регистр TIMSK. |
|||
Очевидно, что назначение команды с константой в форме выражения бо лее понятно, чем с константой в виде числа 0x11.
Для команды Ipm адрес FLASH указывается в регистре Z со сдвигом на 1 разряд, так как младший бит регистра Z определяет байт, который передается по этой команде из FLASH в гО (1 - старший байт, 0 - младший байт). Если адрес FLASH задан меткой (например, меткой ledbcd), про грамма чтения из FLASH будет следующая:
Idi |
ZL, LOW(ledbcd*2) |
определение адреса FLASH eZ со сдвигом |
|
Idi |
ZH, HIGH(ledbcd*2) |
;на 1 разряд умножением метки на 2 |
|
ipm |
|
; чтение в гО младшего байта константы по метке |
|
mov |
rl, гО |
;пересылка младшего байта в rl |
|
inc |
ZL |
;адрес старшего байта (если нет переноса в ZH) |
|
Ipm |
|
; чтение в гО старшего байта константы по метке |
|
Примеры показывают, что использование выражений делает текст про граммы более наглядным и освобождает от необходимости вычисления па раметров для команд вручную.
94