|
|
|
|
Более подробно о макродирективах повторения - IRP и IRPC
Кроме директивы REPT MASM поддерживает еще две директивы макроповторений. Это - IRP (неограниченное повторение) и IRPC (неограниченное повторение
символа). В действительности, ничто не повторяется бесконечно. Вместо этого повторения происходят до тех пор, пока в списке аргументов есть хоть один
аргумент. В Листинге 1-5 приведен пример макроповторения, названного test_vac и предназначенного для добавления элементов в сегмент данных.
Листинг 1-5. Пример макро повторения IRP и его расширение
------------------------------------------------------------------
test_mac MACRO args ;определить "test_mac"
IRP dummy,<&args>
db dummy ;добавить элемент
ENDM ;закончить "IRP"
ENDM ;закончить "test_mac"
test_mac 'one' <-- 1-ый вызов
2 db 'one' ;добавить элемент
test_mac <'two','three','four'> <-- 2-ой вызов
2 db 'two' ;добавить элемент
2 db 'three' ;добавить элемент
2 db 'four' ;добавить элемент
------------------------------------------------------------------
|
При каждом проходе блока повторения в качестве значения dummy используется очередное значение списка аргументов. Используя директиву IRP, мы можем
для выполнения трех действий применить только один вызов макро. При повторном вызове test_ mac блок IRP повторяется db раз для каждой из трех строк
списка аргументов.
Введем для макросов два специальных символа - угловые скобки (< и >). Макро test_mac предполагает наличие только одного аргумента, а мы хотим
переслать ему список аргументов. Угловые скобки выполняют эту функцию, преобразуя текст, заключенный в них, в одиночный литерал. Таким образом,
'two','three','four' интерпретируется как один аргумент, а не три. Однако сами угловые скобки принимающему макро не пересылаются. Внутри test_mac
args имеет значение 'two','three','four', а не <'two','three','four'>. Вот почему в директиве IRP были добавлены угловые скобки.
Однако это объяснение не применимо к строкам! Одиночные кавычки, в которые заключаются строки, не допускаются, а добавление еще одного уровня приводит
к путанице . Если мы используем оператор define byte (определить байт) так:
db 'dummy' ;добавить элемент
|
MASM разворачивает строку следующим образом:
2 db 'dummy' ;добавить элемент
|
что может создать нам довольно много значений dummy, но не сделает то, что мы хотим. Мы можем вызвать использование действительного аргумента
через
db '&dummy' ;добавить элемент
|
но MASM развернет эту строку в
2 db "one" ;добавить элемент
|
Это приведет к появлению специальной ошибки "Чтение текста после конца". Такая же ошибка возникает, если Вы случайно создали бесконечный
рекурсивный вызов макро. В общем случае MASM выберет всю память для сохранения всех используемых символов. Будьте внимательны! Это сообщение об ошибке
выдается до тех пор, пока Вы не прекратите работу MASM, нажав "Cоntrоl-C".
|
|