На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 1 / Введение в МАКРОСЫ Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Введение в МАКРОСЫ

Таким образом, программирование на языке Ассемблера может быть значительно облегчено, если иметь возможность создавать "стенограмму" часто используемых операторов. MASM обеспечивает эту возможность через средства макро. Макро представляют собой "суперкоманды", которые разгружают MASM от части лишней и часто повторяющейся работы по обработке ассемблерной программы. При помощи макросов программисты определяют блоки ассемблерных операторов, а затем, используя конкретные ссылки, указывают MASM на включение соответствующих блоков в ассемблерную программу. В этой главе мы рассмотрим некоторые из таких макросов и понемногу разовьем Ваши способности по написанию собственных инструментариев. Все это позволит Вам соединить скорость выполнения ассемблерной программы с мощностью языка высокого уровня.


Для создания и использования макро необходимо выполнить 2 шага:

Шаг 1. Определение макро

                    ;; Определить    "Требуемую функцию" типа @DosCall
                    @DosCall        MACRO
                                    int 21h   ;для выполнения функции обра-
                                    ENDM      ;титься к MS-DOS

Шаг 2. Использование макро

                                    @DosCall       <--- вызов макро

            В листинге появится следующее:

                                   @DosCall        <--- вызов макро
                    1              int 21h    ;для выполнения функции обра-
                                              ;титься к MS-DOS

При ассемблировании программы оператор DosCall заменяется на оператор int 21h, включая комментарий. Файл листинга содержит строку DosCall как ссылку, однако объектный файл содержит только код для инструкции int 21h. Такая операция известна под названием "подстановка макро" или " расширение макро".


Заметьте, что в предыдущем примере ассемблер вставил в файл листинга символ, обозначающий код расширенного макро. В MASM версии 4 и выше "1" помещается в строки, принадлежащие первому уровню макрорасширения, "2" используется для второго уровня и т.д. В MASM версии 3 и предыдущих версий все строки макрорасширения вне зависимости от уровня помечаются символом плюс (+).


При обработке ассемблером ссылка на макро заменяется на программный код, который это макро представляет. Макро не вырабатывает команду СALL (вызвать), обращенную к коду макро, хотя ссылки на макро порой и используют такой путь.


Подобно другим конструкциям в программировании макросы должны следовать строгим правилам. Форма описания макроса следующая:


            mname      MACRO     argument_list
                       .
                       .      <--- тело макрокода
                       .
                       ENDM

Имя макро определяется как mname, а argument_list представляет собой список аргументов, разделенных запятыми. Если макро не содержит аргументов (как в нашем примере с @DosCall), список аргументов может быть пуст.


Выше был приведен простейший пример. Если это было бы все, что умеет делать макро, то тогда оно было бы довольно примитивным образованием. К счастью, макросы можно подгонять к конкретным условиям применения, используя секцию аргументов. Следующее макро являет собой пример подобной настройки.


            ;; Определить "Печать символа" как PrintChr
            @PrintChr  MACRO    char
                       mov  ah,05
                       mov  dl,&char
                       @DosCall
                       ENDM
         И теперь при использовании макро мы пишем:

            @PrintChr 'A'      <--- вызов макро,

         и в нашем листинге появляется следующее:

            @PrintChr 'A'     <--- вызов макро
            1   mov  ah,05
            1   mov  dl,'A'
            2   int 21h   ;для выполнения функции обратиться к MS-DOS

Конструкция "&char" в макроописании была заменена после вызова макро на "A". (Да, мы ссылаемся на макро, как если бы стоял вызов call. Это удобно, особенно если вспомнить, что команда CALL в явном виде не используется.) Цифра, появляющаяся в начале строки, представляет собой способ, при помощи которого MASM сообщает программисту, что текущий код является результатом макрорасширения. Также заметим, что макро @PrintChr содержит ссылку на ранее определенное макро @DosCall, которое расширяется в оператор int 21h, его представляющий. MASM продолжает "раскручивать" вызовы макро до такого уровня, до которого они вложены, пока не переполнится область памяти таблицы символов. Вложенность являет собой другой способ сообщения, что макро может вызвать макро, которое в свою очередь может вызвать следующее макро и т.д.


Имя char в макро @PrintChr называется формальным аргументом. Всякий раз, когда формальный аргумент char появляется в макро, он заменяется на значение, использованное при вызове макро. В примере с @PrintChr замена char означает, что все появления сhar в макро заменяются на "A".


Заметим, что любое имя, выбранное для формального аргумента,используется исключительно для этого аргумента. Таким образом, если Вы для формального аргумента выбрали имя AX, Вы не можете в данном макро ссылаться на регистр AX!


Аналогичное предупреждение действует и для именования собственно макро. Как только для описания макро Вы выбрали имя add, Вы найдете, что все ссылки на код операции ADD будут вырабатывать в данной программе расширение макро add. При желании, таким образом, можно изменять директивы MASM. Однако очень важно не создавать для имен конфликтные ситуации.


Символ "&" перед char в макро @PrintChr используется для добавления в строку mov dl, значения char. Символ "&" не нужен для раскрутки формального аргумента, что происходит и так, а нужен для сообщения MASM, что char является формальным аргументом, а не частью более длинной строки "mov dl,char". Как показано в следующем примере, оператор "&" особенно важен, если формальные аргументы содержатся в длинных строках.


            Макроописание             Макрорасширение
            @Example MACRO  arg       @Example Y
               mov   dl,arg           1  mov  dl,y    <-правильно
               mov   dl,&arg          1  mov  dl,y    <-правильно
               mov   dl,argZ          1  mov  dl,argZ
               mov   dl,&argZ         1  mov  dl,argZ
               mov   dl,arg&Z         1  mov  dl,YZ   <-правильно
               mov   dl,Xarg          1  mov  dl,Xarg
               mov   dl,X&arg         1  mov  dl,XY   <-правильно
               mov   dl,XargZ         1  mov  dl,XargZ
               mov   dl,X&argZ        1  mov  dl,XargZ
               mov   dl,Xarg&Z        1  mov  dl,XargZ
               mov   dl,X&arg&Z       1  mov  dl,XYZ   <-правильно
               ENDM

Строго говоря, в макро @PrintChr символ "&" не требуется. MASM имеет возможность определить, что char - формальный аргумент, так как после запятой он присутствует в одиночестве. Тем не менее, это хорошая привычка использовать символ "&", даже когда он не требуется, так как он выделяет формальный аргумент при чтении макро и проясняет для MASM, что имелось в виду.


НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz