Каждый оператор внутри макроса может быть инструкцией, директивой или макровключением. Макрос вызывается по своему имени. Чтобы выполнить макрос с именем mac1, необходимо вставить в текст программы команду mac1;. Макровызов не должен содержать дополнительных операторов в строке вызова (т.е. инструкций, директив препроцессора или других макровключений).
Аргументы макроса имеют форму записи:
%n, где n = 0, 1, 2, …, 9;
Следующий пример определяет макрос sum с тремя аргументами:
.MACRO sum(%0, %1, %2);
В коде макроса аргументы маркируются служебными символами %1, %2, %3, и т.д. При вызове макроса служебные символы замещаются величинами аргументов, переданных в макрос. При вызове макроса ему должно быть передано правильное число аргументов. Допустимые передаваемые аргументы и исключения для них приведены в табл. 11.4.
Таблица 11.4 Допустимые передаваемые в макрос аргументы и исключения для них
Операторы ^ и % не могут быть использованы с аргументами, замещающими служебные символы в макроопределении. Тем не менее, аргументы, переданные в макрос, могут использовать эти операторы. Например: read_data(^input);
Директива 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 как адрес приемника}