Главная » Микроконтроллеры
Призовой фонд
на август 2019 г.
1. 1000 руб
Паяльник
2. Тестер компонентов MG328
Паяльник
3. 200 руб.
От пользователей

Директивы ассемблера

Директивы представляют собой команды управления компилятором. Объявление каждой из них должно начинается с точки. Практика показывает, что в любом ассемблере наиболее интенсивно используется только порядка 10…20 директив. Все остальные либо не являются обязательными, либо отвечают за управление, лишь незначительными свойствами компилятора. К “основным”, характерным и для ассемблеров других процессоров, относятся директивы .equ, .org, .def, .сseg, .dseg и т.д. Ну, а такие директивы, как .dq, .exit, .listmac  в реальных программах встречаются действительно очень редко. Ниже приведен перечень, описание и примеры использования директив фирменного ассемблера микроконтроллеров AVR.

Директива .include подставляет текстовый файл в то место программы, где происходит ее употребление. В дополнении к этому сам файл подстановки также может содержать директиву .include. Если файл расположен в директории проекта или в одной из служебных папок, то вместо полного пути, допускается указывать, лишь ссылку на его имя.

Директива .include
Синтаксис написания:
.include "{путь к файлу}"
Пример использования:

.include  "m8def.inc" ;вставка стандартного заголовочного файла

Директива .exit указывает ассемблеру место окончания файла исходного текста. Все операторы, находящиеся после директивы, становятся невидимыми для компилятора. Если .exit встречается в подключаемом файле, то сборка проекта заканчивается строкой, где расположена директива .include. В случае отсутствия директивы .exit, конечной точкой сборки считается последняя строка исходного текста.

Директива .exit
Синтаксис написания:
.exit
Пример использования:

.exit  ;конец файла 

Директивы .nolist и .list служат для управления файлом листинга, который обычно генерируется после сборки проекта. Первая из них запрещает, а другая, соответственно, разрешает вывод информации в файл. Директива .list отменяет действие .nolist и наоборот. 

Директивы .nolist, .list
Синтаксис написания:
.nolist, .list
Пример использования:

.nolist               ;запретить вывод текста файла “m8def.inc”  
.include "m8def.inc" ;в файл листинга программы
.list                 ;продолжить вывод информации

Директива .equ присваивает символьному имени некоторое числовое значение. Символьное имя должно быть уникальным и не может быть изменено в процессе написания программы. Директива не может применяться для назначения символьных имен регистрам общего назначения.

Директива .equ
Синтаксис написания:
.equ {символьное имя} = {выражение}
Пример использования:

.equ DDRB  = 0x17     ;присвоение имени DDRB значения 0x17
.equ PORTB = DDRB + 1 ;присвоение имени PORTB значения 0x18

Директива .set производит то же самое действие, что и .equ. Но в отличии от последней, символьное имя может быть переопределено в любом месте программы.

Директива .set
Синтаксис написания:
.set {символьное имя} = {выражение}
Пример использования:

 .set OFFSET = 0x100     ;присвоение имени OFFSET значения 0x100
 .
 .set OFFSET = OFFSET + 1 ;переопределение значения OFFSET

Директива .def присваивает символьное имя одному из регистров общего назначения. В дальнейшем ходе программы данное имя может быть отменено директивой .undef. 

Директивы .def, .undef
Синтаксис написания:
.def {символьное имя} = {регистр}
.undef {символьное имя} 
Пример использования:

.def temp = R16 ;присвоение регистру R16 имя temp
.undef temp     ;отмена дальнейшего использования имени temp

Директивы .db, .dw, .dd, .dq предназначены для резервирования памяти микроконтроллера под инициализированные данные. Все они могут применяться только в сегментах кода и EEPROM-памяти. Разница между этими директивами заключается в разрядности, представляемых данных. Директива .db резервирует байты, .dw – слова, .dd – двойные слова. В редких случаях может так же оказаться удобным использование директивы .dq, резервирующей 64-разрядные данные.

Директивы .db, .dw, .dd, .dq
Синтаксис написания:
{метка}: .db {8-разрядные данные}
{метка}: .dw {16-разрядные данные}
{метка}: .dd {32-разрядные данные} 
{метка}: .dq {64-разрядные данные} 
Пример использования:

label: 
 .db 0xFA, 250, -6, 0b11111010
 .dw 0xFADE, 64222, -1314, 0b1111101011011110 
 .dd 0xFADEEFCA, 4208914378, -86052918
 .dq 0xFADEEFCAEFBACDEF, 18077149609196178927, -521103510453211

Директива .byte резервирует память под неинициализированные данные в сегментах SRAM и EEPROM.

Директива .byte
Синтаксис написания:
{метка}: .byte {количество резервируемых данных} 
Пример использования:

.equ PAGESIZE = 0x20
buffer: . byte 2*PAGESIZE ;резервирование 64 байт в SRAM 

Директивы .dseg, .eseg, .cseg определяют начало сегментов данных, EEPROM-памяти и кода соответственно. В исходном файле каждый из сегментов может быть представлен только в одном экземпляре. В случае если все эти директивы отсутствуют в программе, компилятор по умолчанию считает, что все операторы расположены в секции кода.

Директивы .dseg, .eseg, .cseg
Синтаксис написания:
.dseg
.eseg
.cseg
Пример использования:

   .dseg          ;начало сегмента данных 
buffer: . byte 32 ;резервирование 32 байт под буфер в SRAM

   .cseg          ;начало сегмента кода
   rjmp  initial
   .
string: .db "ATmega8",0 ;строка, хранящаяся во FLASH-памяти 

   .eseg           ;начало сегмента EEPROM-памяти
_var:  .byte 2     ;резервирование 2-ух байт под переменную _var
_cnst: .db   0xAA  ;резервирование байта под переменную _cnst = 0xAA

Директива .org позволяет задать компилятору начальный адрес в пределах сегментов кода, данных и EEPROM-памяти. В случае применения в сегменте кода, директива определяет адрес размещения 16-разрядного слова программ.

Директива .org
Синтаксис написания:
.org {начальный адрес}
Пример использования:

.equ	SRAM_START = 0x60
.equ	RAMEND     = 0x045F

   .dseg           ;начало сегмента данных
   .org SRAM_START ;резервирование 32 байт в SRAM под буфер,
buffer: . byte 32  ;начиная с адреса 0x60

   .cseg          ;начало сегмента кода
   .org 0          ;вектор сброса по адресу 0
   rjmp  initial
   .
   .org 0x50       ;начало основной программы с адреса 0x50
initial:           
   ldi   temp,high(RAMEND) ;инициализация стека 
   out   SPH,temp
   ldi   temp,low(RAMEND)
   out   SPL,temp
   .

Директивы .macro, .endmacro (.endm), определяющие начало и конец макроса соответственно.

Директивы .macro, .endmacro (.endm)
Синтаксис написания:
.macro {имя макроса}
Пример использования:

  .macro set_bit  ;объявление макроса установки бита порта 
  sbi  @0,@1    ;установить бит @1 регистра порта @0
  sbi  @0-1,@1  ;настроить на вывод линию @1 регистра DDRx    
  .endm
  .
  set_bit PORTB,0 ;установить на линии 0 порта B лог.1

Директива .listmac разрешает расширенный вывод текста макросов в файле листинга. В этом случае содержимое каждого макроопределения, встретившегося в программе, отображается целиком. Если директива не используется, то код в нутрии макроса не приводится.

Директива .listmac
Синтаксис написания:
.listmac
Пример использования:

.listmac ;разрешить разворачивать текст макросов в файле листинга

Директивы .message, .warning, .error предназначены для вывода в окно сборки проекта дополнительной информации о ходе компиляции программы. Директива .message генерирует сообщение для строки, в которой был встречен ее вызов. Применение .warning приводит к выдачи предупреждения, а .error – к сообщению об ошибки. В последнем случае сборка проекта прекращается.

Директивы .message, .warning, .error
Синтаксис написания:
.message "{текст сообщение}"
.warning "{текст предупреждения}"
.error "{текст соодщения об ошибки}"
Пример использования:

.message "Macros has been called here."
.warning "Too high frequency!"
.error "Wrong macro argument!"

Группа директив условной компиляции .ifdef, .ifndef, .if, .else, elif, .endif используются для вставок программного кода в зависимости от различных условий. Директива .ifdef проверяют наличие объявления некоторого символьного имени. За директивой может следовать набор команд, которые будут подставлены в текст, если условие проверки “истина” (имя было объявлено). Директива .ifndef противоположна .ifdef проверяет отсутствие объявления символьного имени. Директива .if производит подстановку кода, когда выполняется условие сравнения, указанное в качестве ее параметра. Команды, которые должны выполняться, в случае если условие директивы .if “ложно” – располагаются после директивы .else. Ветвление типа “если” - “то” может иметь несколько уровней вложения благодаря директиве .elif. Каждый блок проверки, начинающийся с .ifdef, .ifndef, .if, должен быть закрыт директивой .endif.

Директивы if, .ifdef, .ifndef, .else, elif, .endif
Синтаксис написания:
.ifdef {символ} (или .ifndef {символ})
.if {условие}
.else {выражение} (или .elif { условие}) 
.endif
Пример использования:

.macro del_ms  ;макрос, формирующий задержку времени в мс
 .ifndef FREQ  ;если не объявлена константа FREQ (частота в Гц),
  .warning "Undefined FREQ constan!" ;выдаем предупреждение и
  .equ FREQ = 1000000 ;присваиваем по умолчание значение 1 МГц
 .endif
 .equ DELAY = (@0*FREQ)/4000  ;величина задания задержки времени
 .if DELAY > 65535            ;если DELAY размером больше 2 байт, то
  .error “Integer overflow in DELAY!” ;реализация макроса не возможна
 .else                               
  push XL    ;сохраняем в стеке рабочие регистры XL, XH
  push XH
  ldi  XH,high(DELAY) ;цикл задержки времени
  ldi  XL,low(DELAY)
  sbiw XH:XL,1
  brne PC-1
  pop  XH
  pop  XL    ;восстанавливаем из стека рабочие регистры XH, XL
 .endif
.endm
 .
 .equ FREQ = 2000000 ;объявление тактовой частоты 2 МГц
 .
del_ms 25           ;формирование задержки времени в 25 мс

Перейти к следующей части:

Теги:

Котов Игорь Юрьевич Опубликована: 2012 г. 0 0
Я собрал 0 1
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 1 чел.

Комментарии (2) | Я собрал (0) | Подписаться

0
Андрей #
Отличным языком написано, доходчиво, шрифт, цвета, код. Любо дорого. Но вот есть одна задрочка. попал я на вашу статью с гугла и без труда могу перемещаться дальее по ссылке в конце статьи. а вот на начало курса попасть не могу. Я даже не в курсе, есть что то до этой статьи в данном цикле или нет. Равно как и не знал бы о существовании оной главы попади я из поисковика на следующую страницу.
Короче, было бы здорово в конце каждой страницы иметь не только переход на следующую, но и на предыдущую. Ну или на начало статьи. Потому как намереваюсь читать весь цикл.
З.Ы. Сам то я разыщу начало в любом случае. Просто хотелось так сказать поднять градус эффективности материала.
Ответить
0
Nevalyashka #
Я тоже думал над этим вопросом, так же попал на эту страницу от гугл.
Но способ вообщем то есть. Обратите внимание на адресную строку. Если номер в адресной строке поменять то мы попадем на нужный нам материал, на предыдущий, либо которой интересует дальше.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Программатор Pickit3
Программатор Pickit3
Arduino UNO Автомобильный GPS-трекер с GSM/GPRS и дистанционным управлением
вверх