Глава 14. Использование макрокоманд
Макрокоманды позволяют вам задавать имя идентификатора для
текстовой строки или блока кода, которые будут часто использо-
ваться в программе. Однако макрокоманды выходят за рамки простой
подстановки. В Турбо Ассемблере имеются макрооперации, обеспечи-
вающие большую гибкость в определении макрокоманд. В сочетании с
возможностью использования макрокоманд из нескольких строк с ар-
гументами это превращает макросредства Турбо Ассемблера в очень
мощный инструмент. В данной главе описывается, как можно исполь-
зовать в программах текстовые макрокоманды и макрокоманды, состо-
ящие из нескольких строк.
Текстовые макрокоманды
Текстовая макрокоманда - это идентификатор, представляющий
строку текстовых символов. Когда Турбо Ассемблер обнаруживает
идентификатор в выражениях (и в других ситуациях), он подставляет
вместо него текстовые символы. Например, если DoneMsg - это текс-
товая макрокоманда, имеющая значение "Returning to DOS", то сле-
дующий оператор:
GoodBy DB DoneMsg
дает в результате:
GoodBy DB 'Returning to DOS'
Определение текстовых макрокоманд с помощью директивы EQU
Для определения простых текстовых макрокоманд можно исполь-
зовать директиву EQU.Приведем синтаксис определения текстовой ма-
крокоманды:
имя EQU текстовая_строка
где "текстовая_строка" связывается с текстовой макрокомандой с
именем "имя". Для выделения текста вы можете заключить текстовую
строку в угловые скобки (<>), например:
DoneMsg DB <'Returning to DOS'>
Если в режиме MASM вы опустите скобки, то Турбо Ассемблер
будет определять, можно ли свести текстовую строку к выражению.
Если ее вычислить нельзя, Турбо Ассемблер будет интерпретировать
текстовую строку как текстовую макрокоманду (чтобы сохранить
совместимость c MASM). Чтобы обеспечить правильное определение
текстовой строки, нужно всегда заключать ее в угловые скобки.
Рассмотрим следующие ошибки, которые могут возникать, если вы
этого не делаете:
Earth EQU dirt ; Earth = "dirt"
Planet EQU Earth ; Planet = "dirt" (неверно!)
Planet EQU <Earth> ; Planet = "Earth" (верно!)
В режиме Ideal оператор EQU всегда определяет текстовую мак-
рокоманду.
Текстовые макрокоманды являются переопределяемыми. Вы може-
те переопределить текстовую макрокоманду в том же модуле другой
текстовой строкой.
Директивы макрокоманд работы с текстовыми строками
Турбо Ассемблер обеспечивает директивы, которые могут рабо-
тать с текстовыми макрокоманд. Эти директивы доступны в режиме
Ideal и для версий M510, M520 и T300 (как задается директивой
VERSION).
Строковые аргументы для любой из этих директив могут быть
следующими:
- текстовой строкой, заключенной в скобки, например, <abc>;
- именем ранее определенной текстовой макрокоманды;
- выражением с предшествующим символом %, значение которого
эквивалентно числовому представлению строки для текущего
основания.
Директива CATSTR
Директива CATSTR определяет новую текстовую макрокоманду пу-
тем конкатенации строк. Она имеет следующий синтаксис:
имя CATSTR строка[,строка].
Директива CATSTR выполняет конкатенацию слева-направо. Турбо
Ассемблер создает новую текстовую макрокоманду с именем "имя".
Директива SUBSTR
Директива SUBSTR определяет новую текстовую макрокоманду,
которая является подстрокой строки. Она имеет следующий синтак-
сис:
имя SUBSTR строка,выражение_позиции[,выражение_размера]
Новая текстовая макрокоманда с именем "имя" состоит из части
строки , начинающейся с символа в позиции "выражение_позиции" и
длины "выражение_длины". Если вы не указываете "выражение_разме-
ра", новая текстовая макрокоманда содержит остаток строки, начи-
ная с символа в "выражении_позиции". Турбо Ассемблер рассматрива-
ет первый символ строки как позицию 1.
Директива INSTR
Директива INSTR возвращает позицию одной строки внутри дру-
гой. Она имеет следующий синтаксис:
имя INSTR [выражение_начала,]строка_1,строка_2
Турбо Ассемблер присваивает "имя" числовому значению, кото-
рое соответствует первой позиции первого вхождения "строки_2" в
"строку_1". Первый символ "строки_1" имеет позицию 1. Если "стро-
ка_2" в "строке_1" не содержится, то Турбо Ассемблер возвращает
значение 0. Если вы укажете "выражение_начала", то поиск начина-
ется с символа, задаваемого этим выражением. Первый символ строки
находится в позиции 1.
Директива SIZESTR
Директива SIZESTR возвращает длину текстовой макрокоманды
(число символов в строке). Она имеет синтаксис:
имя SIZESTR строка
где "имя" устанавливается в числовое значение, равное длине ука-
занной строки. Нулевая строка <> имеет длину 0.
Примеры макрокоманд работы с текстом
Следующие примеры показывают, как работают эти операции:
VERSION T300
ABC EQU <abc> ; ABC = "abc"
ABC2 EQU ABC ; ABC2 = "ABC"
ABC EQU <det> ; ABC = "det"
; (переопределяется)
ABC3 CATSTR ABC2,<,>,ABC,<,>,ABC2 ;ABC3 = "ABC,DEF,
; ABC"
ABCLEN SIZESTR ABC ; ABCLEN = 3
ABC3LEN SIZESTR ABC3 ; ABC3LEN = 11
COMMA1 INSTR ABC3,<,> ; COMMA1 = 4
COMMA2 INSTR COMMA1+1,ABC3,<,> ; COMMA2 = 8
ABC4 SUBSTR ABC3,5 ; ABC4 = "def,ABC"
ABC5 SUBSTR ABC3,5,3 ; ABC5 = "def"
ABC6 EQU 3+2+1 ; ABC6 = 6
; (числовое
; присваивание)
ABC7 EQU %3+2+1 ; ABC7 = "6"
; (текстовая
; макрокоманда)
ABC8 EQU %COMMA1 ; ABC8 = "4"
Макрокоманды, состоящие из нескольких строк
Макрокоманды, состояние из нескольких строк, позволяют вам
определить в их теле инструкции, директивы или другие макрокоман-
ды, которые будут включаться в исходный код при вызове макроко-
манды. Вы можете указать аргументы макрокоманды, которые Турбо
Ассемблер будет подставлять в тело макрокоманды при ее включении
в модуле.
Существует насколько типов макрокоманд, состоящих из нес-
кольких строк. Одна версия подставляет каждый элемент строки
(один за другим), который является аргументом макрокоманды. Дру-
гая версия повторяет определенное число раз тело макрокоманды.
Наконец, в одном месте вы можете определить еще одну версию, ко-
торая будет много раз вызываться. Все эти версии имеют общее оп-
ределение тела макрокоманды.
Тело макрокоманды, состоящей из нескольких строк
Независимо от содержимого тела макрокоманды, средство обра-
ботки макрокоманд Турбо Ассемблера интерпретирует макрокоманду,
состоящую из нескольких строк, как просто несколько строк текста.
Турбо Ассемблер позволяет вам заменить идентификаторы в теле мак-
рокоманды текстом, заданным при вызове макрокоманды. Это средство
называется подстановкой аргументов. Идентификаторы в теле макро-
команды, которые должны быть заменены, называются формальными
(фиктивными) аргументами. Предположим, например, что идентифика-
тор foo - это формальный аргумент в следующем теле макрокоманды:
PUSH foo
MOV foo,1
Если при вызове данной макрокоманды вы присваиваете foo
текстовую строку AX, то фактическим включаемым в модуль текст бу-
дет:
PUSH foo
MOV AX,1
Правила, которые Турбо Ассемблер использует для распознава-
ния формальных аргументов, достаточно сложны. Рассмотрим, напри-
мер, следующие строки тела макрокоманды, где формальный аргумент
foo не распознается:
symfoo:
DB 'It is foo time'
В общем случае Турбо Ассемблер не будет распознавать фор-
мальный аргумент (без специального указания) в следующих ситуаци-
ях:
- когда он является частью другого идентификатора;
- когда он находится внутри кавычек (' или ");
- в режиме Ideal, когда он указывается после двоеточия не
внутри кавычек.
Использование в макрокомандах символа &
Символ & в теле макрокоманды имеет специальное значение. В
общем случае & отделяет имя формального аргумента от окружающего
текста, благодаря чему Турбо Ассемблер может распознавать его при
подстановке. Если, например, имеется следующее тело макрокоманды:
sym&foo:
DB 'It is &foo time'
и если вы при вызове данной макрокоманды присвоите foo текстовую
строку party, то фактическим включаемым в модуль текст будет сле-
дующее:
symparty:
DB 'It is party time'
В качестве другого примера можно привести следующий:
foo&sym:
DB 'We are in O&foo&o'
Если вы при вызове данной макрокоманды присвоите foo тексто-
вую строку hi, то фактическим включаемым в модуль текст будет
следующее:
hisym:
DB 'We are in Ohio'
Приведем правила для символа &:
- вне заключенных в кавычки строк символ & используется как
разделитель;
- внутри заключенной в кавычки строки и после двоеточия, ко-
торое не находится в заключенной в кавычки строке в режиме
Ideal, символ & должен предшествовать формальному аргумен-
ту (чтобы этот аргумент мог распознаваться);
- при расширении макрокоманды Турбо Ассемблер удаляет один
символ & из группы таких символов.
Последний пункт дает возможность помещать внутри макрокоманд
макроопределения, требующие символа &. Турбо Ассемблер будет уда-
лять только один символ & из группы.
Включение комментариев в тело макрокоманды
В особенно сложных макрокомандах иногда желательно поместить
в теле макрокоманды комментарии, которые не должны включаться при
ее расширении. Это также уменьшает объем необходимой Турбо Ас-
семблеру для обработки макрокоманд памяти. Для этого используйте
комментарий с предшествующей двойной точкой запятой (в начале
строки). Например, следующее тело макрокоманды:
;; Это макрокоманда с комментарием
DB 'макрокоманда с комментарием'
приведет к включению при ее вызове только следующего текста:
DB 'макрокоманда с комментарием'
Примечание: Комментарии с одиночной точкой с запятой
при вызове макрокоманды всегда включаются в макрорасшире-
ние.
Локальные формальные аргументы
В начале тела макрокоманды вы всегда можете включить одну
или более директив LOCAL. Директива LOCAL описывает специальные
формальные аргументы, которым при каждом расширении макрокоманды
будет присваиваться уникальное символьное имя.
Синтаксис директивы LOCAL в теле макрокоманды выглядит сле-
дующим образом:
LOCAL формальный_аргумент_1 [,формальный_аргумент_2].
Если имя "формальный_аргумент", указанное в директиве LOCAL,
не содержит префикс локального идентификатора, то присваиваемое
ему уникальное имя идентификатора будет иметь вид ??xxxx, где
xxxx представляет шестнадцатиричное число. В противном случае
уникальное символьное имя будет иметь вид <локальный_пре-
фикс>xxxx.
Примечание: Подробности о разрешении локальных иденти-
фикаторов и задании локального префикса можно узнать в Гла-
ве 11.
Вы можете использовать формальные аргументы LOCAL для зада-
ния в теле макрокоманды меток, например:
LOCAL @agn, @zero
XOR dx,dx
MOV cx,exp
MOV ax,1
JCXZ @zero
MOV bx,factor
@agn: MUL bx
LOOP @agn
@zero:
Директива EXITM
Директиву EXITM можно использовать в теле макрокоманды для
принудительного завершения ассемблирования включаемого тела мак-
рокоманды. Она имеет следующий синтаксис:
EXITM
Когда Турбо Ассемблер обнаруживает директиву EXITM в теле
макрокоманды, которая включена в исходный код модуля, ассемблиро-
вание расширенного тела макрокоманды немедленно прекращается.
Вместо этого Турбо Ассемблер будет продолжать ассемблирование мо-
дуля после конца макрокоманды.
Для завершения макрокоманды при определенных условиях вы мо-
жете использовать оператор EXITM с директивой условного ассембли-
рования.
Примечание: Директивы условного ассемблирования под-
робнее рассматриваются в Главе 15.
Директива GOTO и макроидентификаторы перехода
Использование директивы GOTO и макроидентификаторов перехода
позволяют вам управлять последовательностью расширения строк мак-
рокоманды. Вы можете поместить цель перехода в любом месте тела
макрокоманды. Она занимает всю строку макрокоманды и имеет следу-
ющий синтаксис:
:идентификатор_перехода
При расширении макрокоманды все макроидентификаторы перехода
отбрасываются.
Директива GOTO сообщает Турбо Ассемблеру, что нужно перейти
на заданную точку исходного кода, а именно - на "идентифика-
тор_перехода". Это позволяет вам поместить GOTO в блоке условного
ассемблирования. Например:
IF foo
GOTO tag1
ENDIF
DISPLAY "foo имеет значение false!"
:tag
; возобновление макрокоманды.
; работает одинаково, независимо от того,
; равно foo false или true
Примечание: Будьте аккуратны и не создавайте при ис-
пользовании директивы GOTO бесконечных циклов. Бесконечные
циклы могут привести к тому, что Турбо Ассемблер исчерпает
доступную память или даже прекратит работу.
Подробнее о директивах условного ассемблирования рассказыва-
ется в Главе 15.
Общие макрокоманды, состоящие из нескольких строк
Турбо Ассемблер связывает тело макрокоманды, состоящей из
нескольких строк (включая директивы, инструкции и другие макроко-
манды) с символьным именем макрокоманды. При использовании имени
макрокоманды в качестве директивы Турбо Ассемблер включает в
программу тело макрокоманды (операторы). Таким образом вы можете
использовать макрокоманду, состоящую из нескольких строк, нес-
колько раз.
Приведем синтаксис общей макрокоманды из нескольких строк
режима Ideal:
MACRO имя список_параметров
тело_макрокоманды
ENDM
В режиме MASM общее определение макрокоманды из нескольких
строк имеет следующий синтаксис:
имя MACRO список_параметров
тело_макрокоманды
ENDM
где "имя" - это имя определяемой вами макрокоманды из нескольких
строк. "Тело_макрокоманды" содержит операторы, которые составляет
тело макрорасширения. В макрокоманду вы можете помещать любые до-
пустимые операторы Турбо Ассемблера (и любое их число). Макроко-
манду завершает ключевое слово ENDM.
В следующем примере определяется макрокоманда с именем
PUSHALL, которая при вызове включает в вашу программу тело макро-
команды, состоящее из трех инструкций PUSH:
PUSHALL MACRO
PUSH AX BX CX DX
PUSH DS SI
PUSH ES DI
ENDM
"Список_параметров" - это список формальных аргументов (их
идентификаторов) макрокоманды. Он имеет следующий синтаксис:
[формальный_аргумент [,формальный_аргумент].]
В макрокоманде вы можете использовать любое число формальных
аргументов (если они не умещаются на одной строке, для продолже-
ния на другой строке можно использовать символ /). Например:
ADDUP MACRO dest,\ ; dest - это первый формальный
; аргумент, а s1,s2 -
; это второй и третий
; аргумент макрокоманды
MOV dest,s1
ADD dest,s2
ENDM
Каждый формальный аргумент имеет следующий синтаксис:
имя_формального_аргумента[:тип_аргумента]
где "имя_аргумента" - это символьное имя, используемое для подс-
тановки (вместо него) фактического параметра, передаваемого мак-
рокоманд при ее вызове. Необязательный "тип_аргумента" задает ка-
кую-то информацию о виде фактического параметра, воспринимаемого
при вызове макрокоманды. Поддерживаются следующие типы:
Типы формальных аргументов Таблица 14.1
-----------------------T----------------------------------------¬
¦ Тип ¦ Значение ¦
+----------------------+----------------------------------------+
¦ REQ ¦ Аргументы не могут быть нулевыми или ¦
¦ ¦ состоять из пробелов. ¦
¦ ¦ ¦
¦ =<текстовая_строка> ¦ Заключенная в кавычки текстовая строка ¦
¦ ¦ задает используемое по умолчанию зна- ¦
¦ ¦ чение аргумента (когда фактический ар- ¦
¦ ¦ гумент является нулевым или состоит из ¦
¦ ¦ пробелов). ¦
¦ ¦ ¦
¦ VARARG ¦ Фактический аргумент состоит из ос- ¦
¦ ¦ тальной части макровызова, интерпрети- ¦
¦ ¦ руемого как список аргументов. Для ¦
¦ ¦ обеспечения этой интерпретации исполь- ¦
¦ ¦ зуются угловые скобки, запятые. ¦
¦ ¦ ¦
¦ REST ¦ Фактический аргумент состоит из ос- ¦
¦ ¦ тальной части макровызова, интерпрети- ¦
¦ ¦ руемого как непосредственный текст. ¦
L----------------------+-----------------------------------------
Вызов общей макрокоманды, состоящей из нескольких строк
Чтобы вызвать общую макрокоманду, используйте в вашей прог-
раммы в качестве директивы имя макрокоманды. Турбо Ассемблер
вставляет в этой точке модуля (поле подстановок всех формальных
аргументов) тело макрокоманды. При вызове общей макрокоманды,
состоящей из нескольких строк, используется следующий синтаксис:
имя_макрокоманды [аргумент [[,]аргументе].]
где "имя_макрокоманды" - это идентификатор макрокоманды. Если вы
вызываете макрокоманду с аргументами, то список аргументов указы-
вается после имени макрокоманды. Вы можете задать любое число
аргументов, но все они должны умещаться на одной строке. Аргумен-
ты нужно отделять друг от друга запятыми или пробелами. При рас-
ширении макрокоманды Турбо Ассемблер заменяет первый формальный
аргумент макроопределения первым передаваемым аргументом, второй
аргумент - вторым аргументом и т.д.
Каждый "аргумент" представляет текстовую строку. Вы можете
задать эту текстовую строку следующими способами:
- как непрерывную группу символов, не содержащую пробелов,
запятых или двоеточий;
- как группу символов, выделенную угловыми скобками (<>),
которая может содержать пробелы, запятые и двоеточия;
- как одиночный символ с предшествующим знаком !, что экви-
валентно заключению символа в угловые скобки;
- как выражение с предшествующим символом %, которое предс-
тавляет текстовое значение выражения, соответствующее те-
кущему выбранному основанию.
Литеральные строки в угловых скобках
Используйте угловые скобки для выделения литеральной строки,
содержащей символы-разделители. Следует использовать следующий
синтаксис:
<текст>
где "текст" интерпретируется как одиночный строковый параметр,
даже если он содержит запятые, пробелы или символы табуляции, ко-
торые обычно разделяют параметры. Используйте данную операцию,
когда вы хотите передать аргумент, содержащий один из таких сим-
волов.
Вы можете также использовать эту операцию, чтобы Турбо Ас-
семблер интерпретировал символ литерально, не придавая ему специ-
альное значение. Например, если вы хотите передать в качестве па-
раметра макровызова точку с запятой (;), то чтобы предотвратить
ее интерпретацию как комментария, вы можете заключить ее в угло-
вые скобки (<;>). При преобразовании заключенной в скобки строки
в текстовый аргумент Турбо Ассемблер убирает только один уровень
угловых скобок. Это позволяет вызывать макрокоманду, требующую
наличия угловых скобок, из другой макрокоманды.
Символ !
Символ ! позволяет вам вызывать макрокоманду с аргументами,
которые содержат специальные символы. Указание этого символа пе-
ред другим символом эквивалентно заключению этого второго символа
в угловые скобки. Например, !; действует также, как <;>. Некото-
рые общие случаи использования данного символа показаны в следую-
щей таблице:
Использование специального символа ! Таблица 14.2
------------------T---------------------------------------------¬
¦ Строка ¦ Полученные в результате символ ¦
+-----------------+---------------------------------------------+
¦ !> ¦ > ¦
¦ ¦ ¦
¦ !< ¦ < ¦
¦ ¦ ¦
¦ !! ¦ ! ¦
L-----------------+----------------------------------------------
Символ вычисления выражения %
Символ % указывает Турбо Ассемблеру, что выражение нужно вы-
числить. Ассемблер преобразует результат выражения к виду ASCII с
текущим основанием. Используйте данный символ, когда в качестве
макроаргумента вы хотите передать строку,представляющую вычислен-
ный результат, а не само выражение. При этом используется следую-
щий синтаксис:
%выражение
где "выражение" может быть либо выражением (использующим любые
допустимые операнды и операции), или именем текстовой макрокоман-
ды. Если это выражение, то создаваемым текстом будет результат
выражения с текущим основанием. Если "выражение" - это текстовая
макрокоманда, то создаваемым тестом будет текст, который предс-
тавляет текстовая макрокоманда. Например, следующий фрагмент
программы:
DEFSYM MACRO NUM
TMP_&NUM:
ENDNUM
TNAME EQU <JUNK> ; определение
; текстовой макрокоманды
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
Директива WHILE
Для повторения тела макрокоманды до того момента, пока опре-
деленное выражение не примет значения 0 (false), вы можете ис-
пользовать макродирективу WHILE. Она имеет следующий синтаксис:
WHILE выражение
тело_макрокоманды
ENDM
Перед каждой итерацией тела макрокоманды Турбо Ассемблер вы-
числяет "выражение". Будьте аккуратны и избегайте бесконечных
циклов, которые привести к тому, что Турбо Ассемблер исчерпает
доступную память или прекратит работу. Приведем пример использо-
вания директивы WHILE:
WHILE 1
;; ничего не делает
ENDM
Макрокоманды повторения строк
Для повторения тела макрокоманды для каждого элемента в
списке или каждого символа в строке вы можете использовать макро-
директивы повторения IRP и IRPC. Каждая из этих директив требует
от вас задания одного формального аргумента. Приведем синтаксис
директивы IRP:
IRP формальный_аргумент, список_аргументов
тело_макрокоманды
ENDM
Директива IRPC имеет следующий синтаксис:
IRP формальный_аргумент, строка
тело_макрокоманды
ENDM
в обоих случаях "формальный_аргумент" - это аргумент, используе-
мый в теле макрокоманды. Конец тела макрокоманды отмечает ENDM.
В синтаксисе директивы IRP "список_аргументов" состоит из
спискам аргументов, разделенных запятыми. Аргументами может быть
любой текст (идентификаторы, строки, числа и т.д.). Форма каждого
аргумента в списке аналогична той, которая описана выше для вызо-
ва общей макрокоманды, состоящей из нескольких строк. Список ар-
гументов всегда нужно заключать в угловые скобки (<>).
В синтаксисе директива IRPC аргумент состоит из одной стро-
ки. Строка может содержать столько символов, сколько вы хотите.
Для каждого аргумента или символа в строке Турбо Ассемблер
будет включать в модуль тело макрокоманды, подставляя вместо фор-
мального аргумента аргумент или символ (когда он его находит).
Например:
IRP reg <ax,bx,cx,dx>
PUSH reg
ENDM
дает следующее:
PUSH ax
PUSH bx
PUSH cx
PUSH dx
а директива IRPC:
IRPC LUCKY,1379
DB LUCKY
ENDM
дает следующее:
DB 1
DB 2
DB 3
DB 4
Используйте директива IRPC аккуратно, поскольку Турбо Ас-
семблер помещает каждый символ в строке в макрорасширение "как
есть", поэтому макрокоманда строкового повторения:
IRPC CHAR,HELLO
DB CHAR
ENDM
может дать не DB 'H','E'','L','L','O', а DB H,E,L,L,O (где каждая
буква интерпретируется как имя идентификатора.
Непосредственная макродиректива %
Непосредственная макродиректива % интерпретирует строку
текста так, как если бы это было тело макрокоманды. Приведем ее
синтаксис:
# строка_тела_макрокоманды
где "строка_тела_макрокоманды" представляет тело макрокоманды,
используемое для непосредственного макрорасширения, например:
SEGSIZE EQU <TINY>
LANGUAGE EQU <WINDOWS PASCAL>
% MODEL SEGSIZE,LANGUAGE ; дает MODEL TINY,WINDOWS PASCAL
Включение расширения макрокоманды в файл листинга
Расширения макрокоманд, состоящих из нескольких строк, обыч-
но включаются в файл листинга. Однако в Турбо Ассемблере предус-
мотрены следующей директивы:
- .LALL
- .SALL
- .XALL
- %MACS
- %NOMACS
которые позволяют управлять листингом макрорасширений.
Примечание: Подробнее об этих директивах рассказывает-
ся в Главе 17.
Назад | Содержание | Вперед