Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка (НСиНК) - лабораторные работы.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
477.18 Кб
Скачать

2.3 Использование Меток в Макросах

Использование меток в макросах имеет следующее ограничение - макрос, в теле которого имеется определение метки, может инстанцироваться только один раз, так как при последующих подстановках будет возникать ошибка повторного определения метки с тем же именем.

Для преодоления данного ограничения в языке существует механизм собственных меток макросов - метка, объявленная внутри макроса со спецификатором own, обрабатывается особым образом так, чтобы в каждой подстановке макроса данная метка имела уникальное среди всех подстановок данного макроса имя.

Например:

macro FEQ ( Res, Arg1, Arg2 )

extern FCmp :label;

own Cont :label;

ar5 = sp;

sp += 2;

[ ar5++ ] = Arg1;

[ ar5 ] = Arg2;

call FCmp;

if carry delayed skip Cont

with Res = false noflags;

sp -= 2;

// cond. skip Cont

if <>0 skip Cont;

Res++;

<Cont>

end FEQ;

Макрос FEQ(), использующий собственную метку Cont для организации внутреннего ветвления, может инстанцироваться более одного раза.

Использование спецификатора own при объявлении метки, возможно, только внутри тела макросов.

2.4 Импорт Макросов из Макробиблиотек

Возможность использования макросов из внешних макробиблиотечных файлов на уровне языка реализует директива

import from.

Объявление внешних макросов с помощью директивы импорта предписывает ассемблеру включить определения указанных макросов из некоторой внешней макробиблиотеки. имя_библиотеки считается чистым именем файла макробиблиотеки; оно должно быть задано без пути и может быть задано без расширения, если расширение файла библиотеки не отличается от стандартного (.mlb).

Список включаемых макросов может быть опущен, в этом случае включаются все макросы указанной библиотеки.

Примеры объявлений внешних макросов:

import mode_constants from com_decl.mlb;

import mode_constants, irqtab_layout from

com_decl.mlb;

import from com_decl.mlb;

Здесь первая директива включает из библиотеки com_decl.mlb один, указанный, макрос, вторая - два макроса, третья - все макросы библиотеки.

Поиск макробиблиотек производится сначала в текущем каталоге, а затем, в порядке следования, в каталогах, указанных ключами командной строки ассемблера -I.

Примечание: Возможна ситуация, когда в новой версии ассемблера макросы из созданной в предыдущей версии макробиблиотеки будут интерпретироваться некорректно, в этом случае необходимо перекомпилировать макробиблиотеку.

3. Примеры простейших программ Пример 1: Пример использования макросов в программе

Исходный текст примера, используемого в данном уроке, содержится в файле step13.asm в каталоге: ..\Tutorial\Step13

Пример демонстрирует описание и подстановку макросов с параметрами, а также использование меток внутри тела макроса.

Функция Copy копирует содержимое одного буфера в другой. В теле функции вызывается макрос, описанный в том же файле и выполняющий непосредственное копирование.

Файл “main.cpp”

// функция Copy объявлена внешней с Си-связыванием

extern "C" void Copy( long *Src, long *Dst );

long A[16]; // массив исходных данных

long B[16]; // массив результатов

int main()

{

for (int i=0; i<16; i++)

A[i] = 0x0807060504030201*i;

Copy( A, B ); // вызов функции Copy

return 0;

}

Файл “step13.asm”

global _Copy: label; // объявление глобальной метки _Copy

// описание макроса, предназначенного для копирования одного массива 64-разрядных слов в

// другой. Первый параметр Исходный массив, второй массив результата, третий количество элементов массива.

macro AAA (Arg1, Arg2, Arg3)

own Loop: label; // объявление метки внутри макроса

gr1 = Arg3; // в gr1 загружается количество итераций

gr1--; // установка флага для вхождения в цикл

<Loop>

// инструкция, содержащая команду отложенного перехода

if > delayed goto Loop with gr1--;

gr2, ar2 = [Arg1++];

[Arg2++] = ar2, gr2;

end AAA;

begin ".textAAA"

<_Copy>

ar5 = ar7 – 2;

push ar0, gr0;

push ar1, gr1;

push ar2, gr2;

ar0 = [--ar5]; // в ar0 адрес исходного массива А

ar1 = [--ar5]; // в ar1 адрес массива результата В

AAA(ar0, ar1, 16); // подстановка макроса ААА

pop ar2, gr2;

pop ar1, gr1;

pop ar0, gr0;

return;

end ".textAAA";

Комментарии к Примеру

Функция Copy использует макрос ААА.

AAA(ar0, ar1, 16);

В качестве первого параметра передается массив А, второй параметр – массив В, третий – число 16.

До использования макроса следует описать тело макроса, описание, как правило, располагают между секциями.

macro AAA (Arg1, Arg2, Arg3)

end AAA;

Описание тела макроса начинается с ключевого слова

macro

затем следует имя макроса, далее в круглых скобках задаются параметры.

Заканчивается описание закрывающей скобкой

end

после которой указано имя макроса.

При подстановке макроса в тело программы формальные параметры заменяются фактическими значениями.

Невозможно в качестве параметра передать фрагмент программного кода, так как при использовании макроса не осуществляется текстуальная подстановка. Макрос подставляется в программу как законченный фрагмент кода.

Подробнее об использовании макросов см. в приложении

A.2.Использование Макросов в Языке Ассемблера.

Если внутри тела макроса требуется использовать метку, то при ее объявлении требуется указать ключевое слово own.

own Loop: label;

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

В случае если требуется использовать макрос, описанный в библиотеке макросов, необходимо в программе указать перед подстановкой

import from M.mlb;

где M.mlb – библиотека макросов, в которой находится необходимый макрос.

Компиляция Примера

Для компиляции примера необходимо в командной строке ввести

команду:

nmcc -g -m Step13.asm main.cpp –oStep13.abs