Материал: 1755

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

#ifdef или .IFDEF – директива условной компиляции

Синтаксис:

#ifdef имя Описание:

Сокращение от #if defined. Все следующие строки до соответствующего #endif, #else или #elif условно ассемблируются, если имя определено прежде.

Пример:

#ifdef FOO

……….. // делает что-то. #endif

#ifndef – директива условной компиляции

Синтаксис:

#ifndef имя Описание:

Сокращенная запись от #if not defined. Противоположность #ifdef. Все следующее строки до соответствующих #endif, #else или #elif условно ассемблируются, если имя не определено.

#if

#elif – директивы условной компиляции

Синтаксис: #if условие

#elif

Описание:

Все следующие строки до соответствующего #endif, #else или #elif условно ассемблируются, если условие является истиной (не равно 0). Условие – любое целое выражение, включая макросы препроцессора, которые расширены (распакованы). Препроцессор распознает оператор defined(name), который возвращает 1, если имя определено, и 0 – в противном случае. Любые не определенные символы, использованные в условии по умолчанию, = 0.

Условие может быть вложенным на произвольную глубину.

#elif оценивает условие так же, как #if, за исключением того, что только что оценено, и если никакой предшествующей ветвлению командой #if … #elif данное условие не было оценено как истина.

Примеры:

#if 0

……….. // Здесь код никогда не компилируется. #endif

#if defined(__ATmega48__) || defined(__ATmega88__)

30

…………. // код специфичный для этих устройств. #elif defined (__ATmega169__)

………… // код специфичный для ATmega169. #endif

Препроцессор AVRASM2 не делает отдельный проход до вызова Ассемблера, он встроенная часть Ассемблера. Это может вызвать некоторую неразбериху, если препроцессор и Ассемблер создают аналогичные разнотипные объекты (например, #if и .if условия). Это также вызывает сбои препроцессора при использовании условий в макросах Ассемблера, которые нужно оценивать, когда макрос распакован, а не когда он определен. Условные выражения не могут распределять начало или конец макроопределения (но могут распределить целое макроопределение, включая начало и окончание).

.ENDIF – директива условного ассемблирования

Завершает условный блок кода после директив .IF, .IFDEF или

.IFNDEF. Условные блоки (.IF...ELIF... .ELSE...ENDIF) могут быть вложенными, но все они должны быть выполнены до конца файла (условные блоки не могут работать в нескольких файлах).

Синтаксис:

.ENDIF

.IFDEF <символ > |.IFNDEF < символ >

.ELIF, .ELSE– директивы условного ассемблирования

.ELIF включит в процесс ассемблирования код, следующий за ELIF, до соответствующего ENDIF или следующего ELIF, если expression является истиной. В противном случае этот код будет пропущен.

.ELSE включит код до .ENDIF, если условия в директиве .IF и условия во всех .ELIF были ложными.

Синтаксис:

.ELIF<expression>

.ELSE

.IFDEF <symbol> |.IFNDEF <symbol>

...

.ELSE | .ELIF<expression>

...

.ENDIF

Пример:

.IFDEF DEBUG

.MESSAGE "Debugging.."

.ELSE

31

.MESSAGE "Release.."

.ENDIF

#else – директива условной компиляции

Синтаксис:

#else

Описание:

Все следующие строки до соответствующего #endif условно ассемблируются, если никакая предшествующая ветка в составе последовательности #if... #elif... не оценена как истина.

Пример:

#if defined(__ATmega48__) || defined(__ATmega88__)

…………. // код специфичный для этих МК

#elif defined (__ATmega169__)

………….. // код специфичный для ATmega169 #else

#error "Unsupported part:" __PART_NAME__ // сообщение об ошибке. #endif

.IF, .IFDEF, .IFNDEF – директивы условного ассемблирования

Условное ассемблирование включает команды из исходного кода в процесс ассемблирования выборочно. Директива IFDEF включит код до соответствующей директивы ELSE, если <symbol> определен. Символ должен быть определен директивами EQU или SET (не будет работать с директивой DEF). Директива IF, если <expression> отлично от 0, включит код до соответствующей директивы ELSE или ENDIF. Возможны до пяти уровней вложенности.

Синтаксис:

.IFDEF <symbol>

.IFNDEF <symbol>

.IF <expression>

.IFDEF <symbol> |.IFNDEF <symbol>

...

.ELSE | .ELIF<expression>

...

.ENDIF

Пример:

.MACRO SET_BAT

.IF @0>0x3F

.MESSAGE "Адрес больше, чем 0x3f" lds @2, @0

sbr @2, (1<<@1)

32

sts @0, @2

.ELSE

.MESSAGE " Адрес меньше или равен 0x3f"

.ENDIF

.ENDMACRO

.ERROR – вывод строки с сообщением об ошибке.

.WARNING – вывод строки с предупреждением.

.MESSAGE – вывод строки с сообщением.

Синтаксис:

.ERROR “строка”

.WARNING “строка”

.MESSAGE “строка” Описание:

.ERROR – (ошибка) выдает сообщение об ошибке, останавливает компиляцию и увеличивает счетчик ошибок Ассемблера, тем самым помогает успешному ассемблированию программы. #error определена в стандарте ANSI C.

Пример:

.IFDEF TOBEDONE

.ERROR "Still stuff to be done.."

.ENDIF

.WARNING – (предупреждение) выдает предупреждающее сообщение и увеличивает счетчик предупреждений Ассемблера. В отличие от error не останавливает компиляцию. Директива .warning не определена в стандарте ANSI C, но обычно реализована в препроцессорах, как, например, в препроцессоре GNU C.

Пример:

.IFDEF EXPERIMENTAL_FEATURE

.WARNING "This is not properly tested, use at own risk."

.ENDIF

.MESSAGE – (сообщение) выдает сообщение и не влияет на счетчики ошибок и предупреждений Ассемблера. .message не определено в стандарте ANSI C.

Пример:

.IFDEF DEBUG

.MESSAGE "Debug mode"

.ENDIF

Для всех директив сообщения включают файловое имя и номер строки, подобно нормальным сообщениям об ошибках и предупреждениях.

33

Макросы препроцессора распаковываются, кроме заключенного внутри двойных кавычек (").

Пример:

.error "Неподдерживаемый МК:" __PART_NAME__

#include или .INCLUDE – включение другого файла

Синтаксис:

1)" file "

2)#include <file>

Описание:

Включение файла. Две формы отличаются тем, что (1) ищет сначала

текущий рабочий директорий и функционально эквивалентна директиве

.include Ассемблера. (2) ищет в установленном месте – обычно в директории C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes.

Обе формы ищут включаемые файлы в известном месте установленным Ассемблером.

Лучше использовать абсолютные имена пути к файлу в директивах #include, так как поиск файлов затрудняется при перемещении проектов между другими директориями/компьютерами. Используйте опцию -I командной строки, чтобы определять путь, или установите его в AVR Studio - Project - Assembler Options, в окошке Additional include path.

Примеры:

#include <m48def.inc> ; Ищет в каталоге Appnotes. #include "mydefs.inc" ; Ищет в рабочем каталоге.

; iodefs.asm:

 

.EQU sreg = 0x3f

; Status register.

.EQU sphigh = 0x3e

; Stack pointer high.

.EQU splow = 0x3d

; Stack pointer low.

; incdemo.asm

 

.INCLUDE iodefs.asm ; Include I/O definitions. in r0,sreg ; Read status register.

.OVERLAP – перекрытие

.NOOVERLAP – неперекрытие

Эти директивы нужны для проектов со специфическими особенностями и не должны использоваться в обычных случаях. Они к настоящему времени влияют только на активный сегмент (cseg/dseg/eseg).

Директивы .overlap/nooverlap выделяют секцию кода/данных, которой будет позволено перекрываться с кодом/данными, определенными гденибудь еще, без генерации сообщения об ошибке или предупреждения. Это полностью независимо от того, что установлено с использованием директивы перекрытия #pragma. Атрибут допустимого перекрытия

34