Разработка устройств на основе цифровых сигнальных процессоров фирмы Analog Devices с использованием Visual DSP++ - Олег Вальпа
Шрифт:
Интервал:
Закладка:
.INCLUDE <имя_файла>;
Если файл, который должен быть включен директивой INCLUDE, находится в текущей директории вместе с программой, в угловых скобках требуется указать только имя файла. Если файл находится в другом каталоге, необходимо указать полный путь к этому каталогу и имя файла (или использовать переменную среды окружения ADII). Например, если файл, который должен быть включен, называется filter.dsp и расположен в директории C:ADSP2181PROG2, тогда директива INCLUDE должна быть задана следующим образом:
.INCLUDE <C:ADSP2181PROG2filter.dsp>;
Это позволит ассемблеру найти файл. Существует и другой способ указания пути к файлу. Так можно указать путь, используя переменную среды окружения ADII с помощью команды:
Set ADII=C:ADSP2181PROG2
Данная команда должна записываться в файле autoexec.bat операционной системы или в командном файле для трансляции программы. Установка ADII, равной пути к каталогу, позволит ассемблеру обнаружить файл. В этом случае можно задавать имя файла без указания полного пути. Файл, включенный директивой INCLUDE, может также содержать внутри себя директиву INCLUDE. Вложение файлов директивами INCLUDE ограничивается только размером свободной оперативной памяти.
Директива INCLUDE допускает использовать принцип модульного программирования. Например, во многих случаях она используется, чтобы развить библиотеку подпрограмм или макросов, которые применяются в различных программах. Вместо того чтобы каждый раз переписывать подпрограммы, можно присоединить макробиблиотеку в ассемблерный модуль, воспользовавшись директивой INCLUDE.
Пример:
.INCLUDE <библиотека_макросов>;
Директива MACROДиректива MACRO создает в программе макрос (набор инструкций). Макрос используется для повторения часто используемых последовательностей инструкций в исходном тексте программы. Передачей аргументов макросу реализуется подобие подпрограммы, которая может быть использована в различных программах. Допускается делать вложение макросов. Макровложения ограничены только размером свободной оперативной памяти. Вложенные макросы должны быть объявлены в определенной последовательности. Первым объявляется внутренний макрос. Внешний макрос объявляется последним. Все константы, используемые в макросах, должны быть объявлены перед объявлением макросов. Макрос определяется двумя директивами. Первая директива имеет формат:
.MACRO имя_макроса (аргумент1, аргумент2, ...);
Завершает макрос директива окончания макроса:
.ENDMACRO;
Каждый оператор внутри макроса может быть инструкцией, директивой или макровключением. Макрос вызывается по своему имени. Чтобы выполнить макрос с именем mac1, необходимо вставить в текст программы команду mac1;. Макровызов не должен содержать дополнительных операторов в строке вызова (т.е. инструкций, директив препроцессора или других макровключений).
Аргументы макроса имеют форму записи:
%n, где n = 0, 1, 2, …, 9;
Следующий пример определяет макрос sum с тремя аргументами:
.MACRO sum(%0, %1, %2);
В коде макроса аргументы маркируются служебными символами %1, %2, %3, и т.д. При вызове макроса служебные символы замещаются величинами аргументов, переданных в макрос. При вызове макроса ему должно быть передано правильное число аргументов. Допустимые передаваемые аргументы и исключения для них приведены в табл. 11.4.
Таблица 11.4 Допустимые передаваемые в макрос аргументы и исключения для них
Аргумент Исключение Константа или арифметическое выражение Нет Символы MACRO, ENDMACRO, CONST, INCLUDE ^буфер ^%n %буфер %%nОператоры ^ и % не могут быть использованы с аргументами, замещающими служебные символы в макроопределении. Тем не менее, аргументы, переданные в макрос, могут использовать эти операторы. Например: read_data(^input);
Директива LOCALДиректива LOCAL задает программные метки, используемые в макросе. Данная директива указывает ассемблеру создавать уникальную версию метки при каждом включении макроса. Это предотвращает ошибку дублирования меток в случае, когда макрос вызывается несколько раз в одном программном модуле. Директива имеет формат записи:
.LOCAL метка1, метка2, ...;
Ассемблер создает уникальные версии меток макроса, добавляя к ним номер. Это можно увидеть в файле листинга с расширением lst. Помните, что для раскрытия макросов в листинге необходимо при запуске программы компилятора asm21 добавить ключ -m.
Ниже приведен простейший пример макроса, позволяющий вставить в любое место программы несколько пустых команд пор.
.MACRO nops;
nop; nop; nop; nop; nop; nop;
.ENDMACRO;
Вызов данного макроса в программе осуществляется командой nops;. Следующий пример показывает, как создать макрос wait с одним параметром и одной локальной меткой.
MACRO wait(%0);
local loop;
cntr=%0;
do loop until ce;
loop: nop;
ENDMACRO;
Этот макрос позволяет организовать в программе функцию задержки на 100 циклов лаконичной записью:
wait(100);
Естественно, что вместо числа 100 можно вписывать любое число в разрешенном диапазоне для счетчика циклов.
Ниже приведен пример макроса, реализующий подпрограмму, которая переносит содержимое буфера данных из одной области памяти в другую.
.MACRO mem_trans (%0, %1, %2, %3, %4) {Использует 5 аргументов}
.LOCAL trans;
I4=%0; {Установить I4 как адрес источника}
I5=%1; {Установить I5 как адрес приемника}
M4=1 {Установить указатель на инкремент 1}
CNTR=%2 {Установить длину буфера}
DO trans UNTIL СЕ; {Перенос данных}
si=%3(I4, M4) {Перенос данных из типа %3 памяти}
trans: %4(I5, M4)=si; {В тип %4 памяти}
.ENDMACRO
Пример вызова этого макроса в программе может быть таким:
mem_trans (^tabl_coef, ^buf, %buf, PM, DM);
Здесь в качестве аргументов в макрос передаются адреса буферов tabl_coef и but, длина буфера but и тип памяти. Заметьте, что зарезервированные ключевые слова PM и DM переданы как аргументы.
Несколько следующих директив определяют формат файла листинга. Файл листинга с расширением lst позволяет представить результаты процесса ассемблирования. Ниже показан пример файла листинга простейшей программы. В этом файле используются следующие информационные поля:
addr — смещение от базового адреса модуля;
inst — код операции;
source line — номер строки исходного файла и код.
Release 5.11 Assembler Version 1.34s 9/19/95
D:TEMAIKSPROGTEST.DSPDOS.dsp Mon Jun 21 17:07:36 2004 Page 1
addr inst source line
1 .module/RAM/ABS=0 example;
2 .PAGEWIDTH 70;
3 {Описание переменных}
4 .var/dm flag;
5
6 {Инициализация переменных}
7 .init flag: 0x000f;
8
9 again:
0000 02010F 10 toggle FL1; /* Инвертировать флаг */
0001 18000Fu 11 jump again; /* Зациклить */
12 .endmod;
Каждая строка в листинге этой программы имеет свой номер. При обнаружении ошибки в какой-либо строке программы компилятор выдает именно этот номер строки. Символ «u» в поле inst показывает, что код операции содержит адрес перехода.
Существует пять директив ассемблера для формирования выходного файла листинга.
Директива NEWPAGEДиректива NEWPAGE вставляет разделители страниц. После такой директивы листинг программы продолжится с новой страницы. Данная директива, как и последующие, применяется для выделения программных фрагментов и оформления листинга программы. Пример ее использования:
.NEWPAGE;
Директива PAGELENTHДиректива PAGELENTH регулярно вставляет разделитель страниц после указанного количества строк. Формат ее записи:
.PAGELENGTH число_строк;
Директива LEFTMARGINДиректива LEFTMARGIN оставляет левое поле с указанным числом столбцов (знакомест символов). Формат ее записи:
.LEFTMARGIN число_столбцов;
Директива INDENTДиректива INDENT осуществляет отступ строк программы в исходном коде с указанным числом столбцов. Формат ее записи:
.INDENT число_столбцов;
Директива PAGEWIDTHДиректива PAGEWIDTH определяет ширину строк листинга с указанным числом столбцов. Формат ее записи:
.PAGEWIDTH число_столбцов;