Реклама:

Макроопределение - это способ дать имя фрагменту кода. После того как макрос определен, программист может вместо фрагмента кода писать имя макроса. В сущности, макрос - это просто имя фрагмента кода. В листинге 7.4 приведена ассемблерная программа для Pentium 4, которая дважды меняет местами значения переменных Р и Q. Вот как выглядит основная цепочка операторов:

MOV ЕАХ.Р MOV EBX.Q MOV Q.EAX MOV Р.ЕВХ

В листинге 7.5 эта последовательность определяется как макрос SWAP.

Листинг 7.4. Смена значений переменных Р и Q без использования макроса

M0V ЕАХ.Р MOV EBX.Q MOV Q.EAX M0V Р.ЕВХ

M0V ЕАХ.Р MOV EBX.Q MOV Q.EAX M0.V Р.ЕВХ

Листинг 7.5. Смена значений переменных Р и Q с использованием макроса

SWAP MACRO

MOV ЕАХ.Р MOV EBX.Q MOV Q.EAX MOV P.EBX ENDM

SWAP

SWAP

Хотя в разных языках ассемблера определение макроса выглядит немного по-разному, во всех оно состоит из одних и тех же базовых частей:

+ заголовок макроса, в котором дается имя определяемого макроса;

+ текст, в котором приводится тело макроса;

+ директива, которая завершает определение (например, ENDM).

Когда ассемблер наталкивается на макроопределение в программе, он сохраняет его в таблице макроопределений для последующего использования. Всякий раз, когда в программе в качестве кода операции будет появляться макрос (в нашем примере - SWAP), ассемблер заменит его телом макроса. Использование имени макроса в качестве кода операции называется макровызовом, а его замена телом макроса - макрорасширением.

Макрорасширение происходит в ходе ассемблирования, а не во время выполнения программы. Этот момент очень важен. Программы, приведенные в листингах 7.4 и 7.5, порождают один и тот же машинный код. По программе на машинном языке невозможно определить, использовались макросы при ее порождении или нет. В полученной программе никаких признаков макросов не остается.

Макровызовы не следует путать с вызовами процедур. Основное отличие состоит в том, что макровызов - это команда ассемблеру заменить имя макроса телом макроса. Вызов процедуры - это машинная команда, которая, будучи вставлена в объектную программу, позднее должна быть выполнена для вызова процедуры. В табл. 7.3 сравниваются макровызовы и вызовы процедур.

Таблица 7.3. Сравнение макровызовов и вызовов процедур

Макровызов Вызов процедуры

Когда совершается вызов?

Во время ассемблирования

Во время выполнения программы

Вставляется ли тело макроса или процедуры в объектную программу каждый раз, когда совершается вызов?

Да

Нет

Вставляется ли в объектную программу, команда вызова процедуры, которая затем выполняется?

Нет

Да

Нужно ли после вызова использовать команду возврата?

Нет

Да

Сколько копий тела макровызова или процедуры появляется в объектной программе?

Одна на каждый макровызов

Одна

Можно считать, что процесс ассемблирования проходит в два прохода. На первом проходе сохраняются все макроопределения, а макровызовы расширяются. На втором проходе обрабатывается полученный в результате текст. Иными словами, исходная программа считывается, а затем трансформируется в другую программу, из которой удалены все макроопределения и в которой каждый макровызов заменен телом макроса. Полученная программа без макросов затем поступает в ассемблер.

Важно иметь в виду, что программа представляет собой строку символов, каковыми могут быть буквы, цифры, пробелы, знаки пунктуации и символы возврата каретки (перехода на новую строку). При макрорасширении определенные подстроки из этой строки заменяются другими символьными строками. Макросы - средство манипулирования символьными строками без изменения их значения.

Макросы || Оглавление || Макросы с параметрами