Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

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

Директивы представляют собой команды управления компилятором. Объявление каждой из них должно начинается с точки. Практика показывает, что в любом ассемблере наиболее интенсивно используется только порядка 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 чел.

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

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

Программатор Pickit3
Программатор Pickit3
iMAX B6 - зарядное для Lion, LiPo, LiFe, Pb, NiCd и NiMH аккумуляторов Сатфайндер
вверх