6.5. Макрооператоры

Пример макрокоманды IRPC на Фиг. 6.7 иллюстрирует, в частности, применение символа "&". Это - оператор макрокоманд, который служит для соединения двух элементов. В данном примере оператор "&" соединяет параметр CHAR со строкой-константой "X". Как вы видите, при этом формируется действительное имя регистра.

Еще одним удобным средством при программировании макрокоманд является оператор LOCAL. Оператор LOCAL задает метку, которая используется только в данной макрокоманде. Эта метка должна быть уникальной для каждого вызова данной макрокоманды. Предположим, что вы хотите написать макрокоманду, в которой должен быть кусок программы следующего вида:


AAAAA:   ADD     AL,[BX]
         INC     BX
         LOOP    AAAAA

При первом вызове этой макрокоманды никаких сложностей не возникает. Однако при ее повторном использовании в той же программе, метка AAAAA появляется второй раз. Ассемблер не может допустить двух меток с одним и тем же именем в одной программе и отмечает это как ошибку. Проблема будет разрешена, если объявить метку AAAAA локальной (LOCAL) для данной макрокоманды. Тогда ассемблер установит сформированное им уникальное имя для каждого случая применения метки AAAAA. Встретив имя типа LOCAL впервые, ассемблер меняет его на имя "??0000". Во второй раз - на имя "??0001" и т.д. Каждое имя в транслируемой программе будет уникальным, поэтому никаких ошибок не возникнет. На Фиг. 6.8 показано использование оператора LOCAL. Здесь макрокоманда PAUSE устанавливает счетчик цикла и затем организует цикл с помощью метки, объявленной LOCAL. Данная макрокоманда позволяет организовывать в выполнении программы паузу переменной длительности. Если в макрокоманде необходимо использовать описатель LOCAL, то он должен быть первым оператором макрокоманды, сразу же следуя за оператором MACRO. pre> Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:00:28 Фиг. 6.8 Использование команды LOCAL Page 1-1 PAGE ,132 TITLE Фиг. 6.8 Использование команды LOCAL PAUSE MACRO TIME LOCAL LABEL MOV CX,TIME LABEL: LOOP LABEL ENDM 0000 CODE SEGMENT ASSUME CS:CODE PAUSE 100 0000 B9 0064 1 MOV CX,100 0003 E2 FE 1 ??0000: LOOP ??0000 PAUSE 1000 0005 B9 03E8 1 MOV CX,1000 0008 E2 FE 1 ??0001: LOOP ??0001 000A CODE ENDS END Фиг. 6.8 Использование команды LOCAL

СимволЗначение
;;Комментарий, используемый только в макроопределении
&Соединение текста с параметром
!Вводить следующий символ без интерпретации
%Преобразовать следующее выражение в значение

Фиг. 6.9 Макросимволы

Существуют специальные символы, которые помогут вам управлять макрокомандами и их параметрами. В таблице на Фиг. 6.9 показаны четыре таких символов с объяснением их значений.

На Фиг.6.10 приведен ассемблерный листинг программы, в которой эти символы применяются. Мы уже видели символ ";;" в некоторых макрокомандах сопроцессора 8087. Этот специальный указатель поля комментариев указывает макропроцессору на необходимость исключить поле комментариев при расширении данной макрокоманды. Это позволит включать в макрокоманду комментарии, не допуская их появления при каждом расширении данной макрокоманды. Применение символа "&" мы также встречали в программе на Фиг. 6.7.

Символ "!" позволяет вам в качестве следующего за ним знака поставить любой символ. Это понадобится, если вы захотите включить в макрокоманду какой-либо специальный символ, например, "%", чтобы он не вызывал при этом никакой макрооперации. И наконец, оператор "%" преобразует символическое имя в числовое значение, которое этому имени в данный момент соответствует. Вы можете воспользоваться этой возможностью для ведения нумерации при генерации макрокоманды. В нашем примере на Фиг. 6.10 макрокоманда нумерует выводимые сообщения в соответствии со значением символического имени VALUE.


Microsoft (R) Macro Assembler Version 5.00                1/1/80 04:00:28
Фиг. 6.10 Специальные символы в макрокомандах                   Page  1-1
PAGE ,132

                         TITLE    Фиг. 6.10 Специальные символы в макрокомандах
0000                     CODE     SEGMENT
                                  ASSUME    CS:CODE,DS:CODE

     = 0000              VALUE    EQU       0
                         EXAMPLE MACRO      PARAMETER
                                  DB        'MSG&PARAMETER'
                                                  ;; Комментарий появится только в определении
                                  INC       AX
                         ENDM
0000                     CODE     SEGMENT
                                  ASSUME    CS:CODE

                                  EXAMPLE %VALUE
0000    4D 53 47 30    1          DB        'MSG0' ;
0004    40             1          INC       AX

0005                     CODE     ENDS
                         END

                                  Фиг. 6.10 Специальные символы в макрокомандах