Символ вычисления выражения %
Символ % указывает Турбо Ассемблеру, что выражение нужно вычислить. Ассемблер преобразует результат выражения к виду ASCII с текущим основанием. Используйте данный символ, когда в качестве макроаргумента вы хотите передать строку,представляющую вычисленный результат, а не само выражение. При этом используется следующий синтаксис:
%выражение
где "выражение" может быть либо выражением (использующим любые допустимые операнды и операции), или именем текстовой макрокоманды. Если это выражение, то создаваемым текстом будет результат выражения с текущим основанием. Если "выражение" - это текстовая макрокоманда, то создаваемым тестом будет текст, который представляет текстовая макрокоманда. Например, следующий фрагмент программы:
DEFSYM MACRO NUM TMP_&NUM: ENDNUM
TNAME EQU ; определение ; текстовой макрокоманды DEFSYM %5+4 DEFSYM %TNAME
приведет с следующему макрорасширению:
TMP_9: TMP_JUNK:
Переопределение общей макрокоманды, состоящей из нескольких строк
Общие макрокоманды, состоящие из нескольких строк, вы можете переопределять. Новое определение автоматически заменяет старое определение. Все предшествующие места, где макрокоманда уже была вызвана, не изменяются. Во всех вызовах макрокоманды, следующих за переопределением, используется новое определение.
Удаление общей макрокоманды: директива PURGE
Для удаления макрокоманд вы можете использовать директиву PURGE. Директива PURGE имеет следующий синтаксис:
PURGE имя_макрокоманды, [имя_макрокоманды].
Директива PURGE удаляет определение макрокоманды, состоящей из нескольких строк, с именем "имя_макрокоманды" После использования директивы PURGE Турбо Ассемблер больше не интерпретирует идентификатор PURGE как макрокоманду, например:
ADD MACRO a1,a2 SUB a1,a2 ENDM ADD ax,bx ; этот вызов даст SUB ax,bx PURGE ADD ADD ax,bx ; теперь это не макрокоманда, поэтому вы получите ADD ax,bx
Вы можете сразу удалить этой директивой несколько макрокоманд, разделив их имена запятыми. Отметим однако, что идентификатор удаленной макрокоманды можно переопределить только другой макрокомандой.
Определение вложенных и рекурсивных макрокоманд
Операторы в теле макрокоманды могут включать в себя операторы, вызывающие или определяющие другие макрокоманды. Возьмем следующий пример:
MCREATE MACRO opname, op1,op2,op3,op4,op5,op6,op7 IFNB opname DO & opname MACRO op,count IF count LE 4 REPT count opname op,1 ENDM ELSE MOVE CL,count opname op,CL ENDIF EMDM ; конец DOopname MCREATE op1,op2,op3,op4,op5,op6,op7 ; рекурсия! ENDIF ; конец if ENDM ; конец макрокоманды MCREATE
После вызова:
MCREATE ror,rol,rcl,rcr,shl,sal,sar
будут созданы дополнительные макрокоманды DOror, DOrol и т.д., которые можно использовать следующим образом:
DOshr ax,5 DOrcr bx,3
Рекурсивные макрокоманды можно вызывать со списком параметров и задавать их таким образом, что они будут работать с переменным числом параметров (от 0 до максимального числа параметров). Для этого макрокоманда должна использовать первый параметр для выполнения ее макрорасширения, а затем вызывать сама себя с оставшимися параметрами. При каждой рекурсии остается на один параметр меньше. В конце концов, будет последняя рекурсия без параметров.
Когда вы вызываете макрокоманду рекурсивно, всегда требуется как-то проверить конец рекурсии. Обычно при наличии передаваемого параметра это делается в теле макрокоманды с помощью условного оператора IFNB. Приведем простой пример рекурсивной макрокоманды:
PUSH MACRO r1,r2,r3,r4,r5,r6,r7,r8 IFNB r1 PUSH r1 PUSH r2,r3,r4,r5,r6,r7,r8 ENDIF ENDM
Счетчик повторения макрокоманды
Для повторения тела макрокоманды заданное число раз вы можете использовать директиву повторения REPT. Для этого используется следующий синтаксис:
REPT выражение тело_макрокоманды ENDM
где "выражение" указывает Турбо Ассемблеру, сколько раз нужно повторить тело макрокоманды, заданное между директивами REPT и ENDM. При вычислении "выражения" должна получаться константа. Оно не должно содержать имен идентификаторов с опережающими ссылками. Чтобы отметить конец блока повторения, используйте директиву ENDM. Например, следующий код:
REPT 4 SHL ax,1 ENDM
даст в результате следующее:
SHL ax,1 SHL ax,1 SHL ax,1 SHL ax,1
1 2 3 4 5 6
8 8 8
|