Другая техника определения макроинструкций внутри других состоит в использовании директивы «fix
», которая становится полезной, когда некоторый макрос только начинает определение другого, без его закрытия. Например:
macro tmacro params
{
macro params {
}
MACRO fix tmacro
ENDM fix }
определяет альтернативный синтаксис определения макросов, который выглядит как:
MACRO stoschar char
mov al,char
stosb
ENDM
Имейте в виду, что таким образом заданное определение должно быть создано с применением директивы «fix
», так как перед тем, как процессор ищет знак «}
» во время определения макроса, обрабатываются только символьные константы высшего приоритета! Может возникнуть проблема, если требуется выполнить некоторые дополнительные задания в конце такого определения, но есть еще одно свойство, которое в таких случаях поможет вам. А именно возможно поместить любую директиву, инструкцию или макроинструкцию сразу после символа «}
», который заканчивает макроинструкцию и она будет обработана так же, как если бы была на следующей строке.
2.3.4 Структуры
«struc
» — это специальный вариант директивы «macro
», который используется для определения структур данных. Макроинструкции, определенные директивой «struc
», когда используются, должны предваряться меткой (как директивы определения данных). Эта метка будет также присоединена к началу каждого имени, начинающегося с точки, в содержании макроинструкции. Макроинструкция, определенная с использованием директивы «struc
», может иметь такое же имя, как макросы, определенные с использованием директивы «macro
». Структурная макроинструкция не будет мешать обычному макросу, выполняющемуся без метки перед ним и наоборот. Все правила и свойства, касающиеся стандартных макросов, применимы к структурным макроинструкциям.
Вот пример структуры:
struc point x,y
{
.x dw x
.y dw y
}
Например «my point 7,11
» определит структуру, помеченную «my
», содержащую две переменные: «my.x
» со значением 7 и «my.y
» со значением 11.
Еслигде-то в определении структуры находится имя, состоящие из одной лишь точки, оно заменяется на имя метки для данного примера структуры и эта метка таким образом не будет определена автоматически, позволяя полностью задать определение. Следующий пример использует это свойство, чтобы расширить определение директивы «db
» с возможностью вычисления размера определяемых данных:
struc db [data]
{
common
. db data
.size = $ —.
}
Таким образом строка «msg db 'Hello!',13,10
» определит так же константу «msg.size
», равную размеру определяемых данных в байтах.
Определение структур данных, адресованных регистрами или абсолютными значениями может быть сделано структурными макроинструкциями с использованием директивы «virtual
» (смотрите 2.2.3).
«restruc
» удаляет последнее определение структуры, так же как «purge
» делает с макросами и «restore
» с символьными константами. Директива имеет тот же синтаксис — за ней должно следовать одно или несколько имен структурных макросов, разделенных запятыми.
2.3.5 Повторение макроинструкций
Директива «rept
» — это специальный вид макроинструкций, который делает заданное число дубликатов блока, заключенного в фигурные скобки. Простой синтаксис — число, следующее за «rept
» (это не может быть выражение, так как препроцессор не совершает вычисления, если вам нужны повторения, базирующиеся на выражениях, вычисленных ассемблером, используйте одну из директив, обрабатываемых ассемблером, смотрите 2.2.2), и блок кода, заключенный между знаками «{
» и «}
». Простейший пример:
rept 5 { in al,dx }
создает пять дубликатов строки «in al,dx
». Блок инструкций определяется таким же образом, как для стандартных макросов, и допускаются все специальные операторы и директивы, которые могут использоваться только внутри макроинструкций. Если заданное число равно нулю, блок просто пропускается, как если бы вы определили макрос, но не использовали его. За количеством повторений может следовать имя символа-счетчика, который символьно будет заменяться на номер текущего повторения. Таким образом: