- •Лекция 23
- •Схема трансляции программы с
- •Макросы
- •Макросы
- •Примеры макросов
- •Достоинства и недостатки макросов
- •Использование макросов
- •Использование макросов
- •Использование макросов
- •Использование макросов
- •Использование макросов
- •Пример использования
- •Макродирективы
- •Директивы WHILE и REPT
- •Пример использования WHILE и REPT
- •Директива IRP
- •Директива IRPC
- •Директивы условной
- •Директивы условной компиляции
- •Директивы условной компиляции
- •Директивы IF и IFE
- •Директивы IF и IFE
- •Директивы IFDEF и IFNDEF
- •Директивы IFDEF и IFNDEF
- •Директивы IFB и IFNB
- •Директивы IFB и IFNB
- •Директивы IFIDN, IFIDNI, IFDIF и IFDIFI
- •Директивы IFIDN, IFIDNI, IFDIF и IFDIFI
- •Директивы IFIDN, IFIDNI, IFDIF и IFDIFI
- •Вложенные
- •Директивы генерации ошибок
- •Безусловные директивы генерации ошибки
- •Условная генерация пользовательской ошибки
- •Условная генерация пользовательской ошибки
- •Условная генерация пользовательской ошибки
- •Пример с использованием константных выражений
Лекция 23
Макросы
Схема трансляции программы с
макросамиИсходная программа на Ассемблере (содержит макросы)
1-ая фаза трансляции: |
макроассемблер |
(макрогенератор) |
Исходная |
программа во |
внутреннем |
представлении |
компилятора |
(без макросов) |
2-ая фаза трансляции: |
ассемблер |
Объектный модуль |
Макросы
В трансляторах TASM и MASM существует возможность описывать и использовать макросы. Простейшим макросом, встроенным в перечисленные трансляторы, является макрос equ, который позволяет создавать автозамены. Для этого используется следующая синтаксическая конструкция:
имя_идентификатора equ строка или числовое выражение
Наример: |
|
|
||
arr_size |
equ |
20 |
;объявление размерности массива |
|
akkum |
equ |
eax |
;переименование регистра EAX |
|
arr_elem equ |
array[edx] |
;обращение к элементу массива |
||
… |
|
|
|
|
array |
db |
arr_size dup(0) |
|
|
num |
dw |
arr_size |
|
|
… |
|
|
|
|
cycl0: |
mov |
akkum, arr_elem |
|
|
|
|
|
||
|
|
add |
akkum, 20 |
|
|
|
mov |
arr_elem, akkum |
|
|
|
inc |
edx |
|
|
|
loop |
cycl0 |
|
|
|
|
|
|
Макросы
В трансляторе могут содержаться некоторые другие описания макросов.
Макрокоманда – строка, содержащая некоторое символическое имя – имя макрокоманды, предназначенную для того, что бы быть замещенной одной или несколькими другими строками.
Шаблон-описание макрокоманды называется макроопределением. Для описания макроопределения используют следующую синтаксическую конструкцию:
имя_макро_команды macro список_формальных_аргументов
тело макроопределения
Endm
Размещение макросов:
в начале исходного текста программы,
в отдельном файле, который подключается в начале текста программы с помощью директивы include,
в макробиблиотеке (подключается также с помощью директивы include).
Примеры макросов
Макрос настройки на сегмент данных |
Макрос конца программы |
|||
init_ds macro |
exit_m |
macro |
||
|
mov |
ax, @Data |
mov |
ax, 4c00h |
|
mov |
ds, ax |
int |
21h |
endm |
|
endm |
|
|
Макрос вывода строки на экран: |
|
|
||
out_str macro str |
|
|
||
|
push |
ax |
|
|
|
mov |
ah, 09h |
|
|
|
mov |
dx, offset str |
|
|
|
int |
21h |
|
|
|
pop |
ax |
|
|
endm |
|
|
|
|
Макрос очистки регистра |
|
|
||
cls_reg |
macro rg |
|
|
|
|
xor |
rg, rg |
|
|
endm |
|
|
|
|
|
|
|
|
|
Достоинства и недостатки макросов
Вотличие от процедуры, текст которой не изменен, макроопределение
впроцессе макрогенерации может меняться в соответствии с с
набором фактических параметров. При этом коррекции могут подвергаться как операнды команда, так и сами команды. Процедуры в этом отношении менее гибки.
При каждом вызове макрокоманды ее текст в виде макрорасширения вставляется в программу. При вызове процедуры микропроцессор вызывает передачу управления на начало процедуры, находящейся в некоторой области памяти в одном экземпляре. Код в этом случае получается более компактным, хотя быстродействие несколько снижается за счет необходимости осуществления переходов.
Использование макросов
Макрокоманду можно использовать в тексте программы в формате: имя_макрокоманды список_фактических_параметров
Значения фактических параметров используются вместо формальных параметров при вставке тела макрокоманды в текст программы.
Процесс замещения макрокоманды ее телом называется макрогенерацией, а результатом этого процесса является макрорасширение.
Пример |
|
|
|
|
|
|
cls_reg |
ax |
-> |
xor |
ax, ax |
|
out_str |
mess |
-> |
push |
ax |
|
|
|
|
mov |
ah, 9h |
|
|
|
|
mov |
dx, offset mess |
|
|
|
|
int |
21h |
|
|
|
|
pop |
ax |
|
|
|
|
|
|
Использование макросов
Каждый фактический аргумент представляет собой строку символов, для формирования которой применяются следующие правила.
Строка может состоять:
Из последовательности символов без пробелов, точек, запятых, точек с запятой.
Из последовательности любых символов, заключенных в угловые скобки <…>.
Для того, чтобы указать некоторый символ внутри строки, представляющий фактический параметр, является собственно символом, а не чем-то иным, применяется специальный оператор «!». Этот оператор ставится непосредственно перед символом, и его действие эквивалентно заключению данного символа в угловые скобки.
Если требуется вычисление в строке некоторого константного выражения, то в начале этого выражения нужно поставить знак %.
% константное выражение – значение константное выражение вычисляется и подставляется в текстовом виде в соответствии с текущей системой счисления.
Использование макросов
Впроцессе генерации макрорасширения компилятор ассемблера ищет в тексте макроопределения последовательности символов, совпадающие с теми последовательностями символов, из которых состоят формальные параметры. После обнаружения такого совпадения формальный параметр из тела макроопределения заменяется соответствующим фактическим параметром из макрокоманды. Этот процесс называется подстановкой аргументов.
Использование макросов
Полный синтаксис формального аргумента: имя_формального_аргумента[:тип]
где тип может принимать значения:
REQ – требуется обязательное явное задание фактического аргумента при вызове макрокоманды;
=<любая строка> - задание значения по умолчанию, которое используется, если этот аргумент при вызове макрокоманды не задан.