При программировании устройств на базе AVR ассемблер AVRASM является стандартом. Беда в том, что он есть только под Windows. В других операционных системах существуют такие компиляторы, как arva, avr-as - основные аналоги атмеловского AVRASM. Я пользуюсь avra. Он почти полностью идентичен AVRASM и в довесок имеет расширенный язык макроопределений. Если не пользоваться расширенными возможностями avra, код для AVRASM будет компилироваться на avra и наоборот. Отсюда и далее я буду использовать avra.
Например, код на рисунке
первая строка с директивой .device дает компилятору указание собирать для микропроцессора серии atmega32. Далее определяется метка Init, которая в дальнейшем будет использоваться для реализации бесконечного цикла. После идет nop - не опрерация и в конце - rjmp Init - безусловный переход на метку Init.
компиляция программы avra test.asm даст там такой вывод:
Видно, что прошивка занимает 3 слова (6 байт), при этом ни оперативка SRAM, ни EEPROM не используются.
В коде на рисунке 1 явно не указаны сегменты, о умолчанию считается, что все располагается в сегменте кода (.cseg).
Но вернемся все-таки к обзору свойств компилятора avra:
- Поддержка расширенного набора директив препроцессора (.define, .undef, .ifdef, .ifndef, .if, .else, .endif, .elif, .elseif, .warning). Они действуют аналогичным образом, что и в Си, так что если ты знаком с ним, никаких трудностей в использовании данных директив не будет.
- В AVRA появились новые функции для написания макросов. Это должно способствовать повторному использованию кода, например, при создании собственной библиотеки. В avrasm есть макросы, но их парамеры не типизированы, то есть вызывая макрос, вы в качестве параметра можете передать абсолютно любое значение, будь то регистр, ссылка на память, адрес. Это не совсем удобно, особенно если один и тото же макрос используется для операций с 1,2,4,8-байтовыми числами. В AVRA добавлена возможность писать типизированные макросы.
- Поддержка отладки. AVRA создает coff-файл каждый раз, когда сборка проходит успешно. Этот файл позволяет AVR Studio или любому совместимому с coff отладчику имитировать или эмулировать программу.
- Поддержка мета-определений. Они помогают отслеживать версии вашего программного обеспечения, а также могут быть использованы для создания серийных номеров конкретных клиентов.
- Циклы в макросах. Макро-расширения AVRA позволяют организовывать циклы в макросах. Предусмотрена возможность генерации уникальных меток для переходов.
AVRA предлагает ряд директив, которые не являются частью ассемблера Atmel. Они должны помочь вам в создании универсального и модульного кода.
Директива .define определяет переменную препроцессора, которую можно использовать для построения модульного кода или исключения повторного включения подключаемых модулей.
Например .define twi мы определяем переменную twi, которую можно использовать в языке препроцессора и не только.
Директивы .if .elseif .else .endif - используются для подключения различных кусков программы. Например:
.ifndef twi
.define twi 0
.endif
.if twi==0
.include "twi.asm"
.elseif twi==1
.include "i2c.asm"
.endif
Здесь вы видим, что в зависимости от значения подключается либо аппаратная, либо программная реализация двухпроводного интерфейса. Использование директив препроцессора позволяет писать переносимые программы.
В AVRA появилась расширенная поддержка макросов. Как я уже упоминал, это нововведение относится к типизации макросов. Существует несколько типов:
- _8,_16,_24,_32,_40,_48,_56,_64 - регистровые значения соответствующей битности
- _i - непосредвтвенные значения (константы или метка в SRAM/FLASH)
- _v - пустой параметр
соответственно может писать теперь типизированные макросы, например:
Обратите внимание на следующие вещи:
- объявление пустого макроса без параметров обязательно, иначе ассемблер будет ругаться на предмет его (макроса) отсутствия.
- при вызове расширенных макросов параметры передаются в квадратных скобках
- При объявлении void параметра он не нумеруется в списке подстановок (см Рисунок 5)
Циклы в макросах. Как понимаешь, макрос - это не подпрограмма, текст макроса полностью копируется в программу, поэтому при организации циклов мы должны каким-то образом помечать возможные переходы. В стандартном AVRASM существуют следующие подходы:
- Запоминать адрес точки перехода в локальную макро-переменную
.macro Loop
ldi r16, 10
.set M=PC
nop
dec r16
brne M
.endm
2. Передавать дополнительным параметром номер вызова
.macro Loop
ldi r16, 10
M#@0:
nop
dec r16
brne M#@0
.endm
и вызывать так: Loop 1.
Дугой возможный вариант совмещать макрос и вызов подпрограммы. Так можно уйти от необходимости организовывать циклы в макроопределениях.
AVRA предоставляет иной способ организации циклов в макросах через метки с параметром подстановки %.
Например, предыдущий пример можно переписать так:
.macro Loop
ldi r16, 10
M%:
nop
dec r16
brne M%
.endm
А вот ниже смотри листинг кода, что сгенерировал ассемблер.
Обрати внимание, что номер метки автоматически увеличивается при каждом вызове макроса. При первом вызове макроса Loop внутренняя метка получил индекс 1, при втором - 2.