Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Тема 6.9  Макросы. Микрооператоры подстановки. Локальные метки макроса.




 

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

 

Сначала она переводится на «чистый» ассемблер, то есть преобразуется к такому виду, где нет никаких макросредств. Этот этап называется этапом макрогенерации, его осуществляет специальный транслятор ― макрогенератор.

На втором этапе полученная программа переводится в машинный код. Это этап ассемблирования, его осуществляет ассемблер.

Трансляция программы, написанная на макроязыке, занимает больше времени, чем трансляция программы на чистом языке ассемблера. Но макроязык предоставляет больше возможностей, поэтому писать большие программы проще на макроязыке.
Макрогенератор и ассемблер могут взаимодействовать двояко.

 

Они могут действовать независимо друг от друга: сначала текст программы обрабатывает макрогенератор и только затем начинает работать ассемблер. Такой способ достаточно прост для понимания и для реализации используется достаточно часто, однако у него есть серьезный недостаток: макрогенератор, работая до ассемблера, не может воспользоваться информацией, извлекаемой из текста программы ассемблером. Например, в макросредствах нельзя использовать то, что после директивы

N equ 10

имя N обозначает число 10, так как эта директива относится к чистому ассемблеру и будет обработана только им. Из-за подобного рода ограничений приходится усложнять макроязык.

Макрогенератор и ассемблер могут действовать совместно, чередуя свою работу: первым каждое предложение программы просматривает макрогенератор; если эта конструкция макроязыка, то макрогенератор соответствующим образом преобразует ее в группу предложений ассемблера и передает их на обработку ассемблеру, а если это предложение ассемблера, то макрогенератор сразу передает его ассемблеру. В таких условиях в конструкциях макроязыка уже можно ссылаться на объекты (например, константы) " чистого ассемблера".

Стандартные функции могут быть определены в библиотеке макрокоманд и доступны при дальнейшем программировании. Число операций повторного кодирования уменьшается, уменьшается и количество ошибок.

Блоки повторения

Иногда в программе приходится выписывать несколько раз подряд один и тот же (или почти один и тот же) фрагмент, и хотелось бы, чтобы мы сами выписали этот фрагмент только раз, а макрогенератор размножил его нужное количество раз. Такая возможность предусмотрена в языке ассемблер, и реализуется она с помощью блоков повторения (repeat blocks).

Структура блока повторения

 

< заголовок> < тело блока> ENDM

< тело блока> ― любое число любых предложений (в частности, ими могут быть снова блоки повторения),

ENDM ― директива, указывающая на конец тела и всего блока повторений.

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

 

REPT–блоки

IRP–блоки

IRPC–блоки

REPT–блоки

Этот тип блоков повторения записывается следующим образом:

REPT k < тело блока> ENDM

k ― константное выражение с неотрицательным значением. Это выражение должно быть таким, чтобы можно было вычислить его сразу (например, в нем не должно быть ссылок вперед). Вычислив значение k, макрогенератор создаст k точных копий тела блока и подставляет их в окончательный текст программы:

До макрогенерации После макрогенерации
REPT 3 SHR AX, 1 ENDM SHR AX, 1 SHR AX, 1 SHR AX, 1

 

До макрогенерации После макрогенерации
N EQU 6 REPT N-4 DB 0, 1 DW? ENDM N EQU 6 DB 0, 1 DW? DB 0, 1 DW?

В блоках повторения довольно часто используется директива присваивания (=). Для описания 100-байтового массива X, элементы которого имеют начальные значения от 0 до 99, можно так

X DB 0, 1,..., 99

 

До макрогенерации После макрогенерации
X DB 0 K=0 REPT 99 K=K+1 DB K ENDM X DB 0 K=0 K=K+1 DB K K=K+1 DB K...; 99 таких пар

WHILE-блоки

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

 

структура WHILE-блока

 

WHILE k < тело блока> ENDM

макрос демонстрирует резервирование памяти длиной len байтов с использованием директивы WHILE:

WHILE len DB 0 len=len-1 ENDM

IRP–блоки

Блоки повторения этого типа имеют следующий вид

IRP p, < v1,..., vk> < тело блока> ENDM

Запись в уголках < v1,..., vk> ― это явно указываемые символы, а не метасимволы. Здесь p ― некоторое имя, оно играет роль формального (фиктивного) параметра и используется в предложениях тела макроса. vi ― это фактические параметры; это любые тексты (возможно, и пустые), но, чтобы не было путаницы, они должны быть сбалансированы по кавычкам и не должны содержать запятые, точки с запятой и уголки вне кавычек (если это ограничение надо нарушить, то следует воспользоваться микрооператорами). Параметры vi перечисляются через запятую, а вся их совокупность обязательно заключается в угловые скобки.
Встречая такой блок макрогенератор заменяет его на k копий тела (по одной на фактический параметр), причем в i-той копии все вхождения имени p заменяются на vi:

До макрогенерации После макрогенерации
IRP REG, < RAX, RBX, RCX] PUSH REG ENDM PUSH RAX PUSH RBX PUSH RCX

Формальный параметр локализуется в теле блока (им нельзя пользоваться вне блока) и может быть любым именем. Если оно совпадает с именем другого объекта программы, то в теле блока оно обозначает именно параметр, а не объект. Имя BX обозначает параметр, а не регистр, поэтому по данному блоку будет построен следующий фрагмент окончательной программы:

До макрогенерации После макрогенерации
IRP BX, < 1, 5> ADD AX, BX ENDM ADD AX, 1 ADD AX, 5

Замены формального параметра на фактические ― это чисто текстуальные подстановки, без учета смысла: просто один участок p заменяется на другой vi. При этом параметром p можно обозначить любую часть предложения (в частности, участки комментария) или даже целиком все предложение (однако два и более предложения он не может обозначать), лишь бы после замены p на vi получались правильные предложения:

До макрогенерации После макрогенерации
IRP Q, < DEC WORD PTR, L: INC> Q W JMP M2 ENDM DEC WORD PTR W JMP M2 L: INC W JMP M2

В теле блока повторения заменяется только формальный параметр, другие имена (например, имена констант переносятся в копии тела без изменений:

До макрогенерации После макрогенерации
N EQU 1 IRP P, < A, B> P EQU N ENDM N EQU 1 A EQU N; но не A EQU 1 B EQU N

IRPC–блоки

Блоки этого типа записываются следующим образом:

IRPC p, s1... sk < тело блока> ENDM

p ― формальный параметр

si ― символы. Это могут быть любые символы, кроме пробелов и точек с запятой (считается, что с точки с запятой начинается комментарий, а пробел заканчивает операнд; если надо указать точку с запятой или пробел, то всю последовательность символов следует заключить в угловые скобки).

Встречая IRPC–блок, макрогенератор заменяет его на k копий тела блока (по одной на каждый символ), причем в i-ой копии все вхождения p будут заменены на символ si.

До макрогенерации После макрогенерации
IRPC D, 17W ADD AX, D ENDM ADD AX, 1 ADD AX, 7 ADD AX, W

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

При использовании блоков повторения (и макросов) возникает ряд проблем с записью формальных и фактических параметров. Эти проблемы решаются с помощью макрооператоров ― операторов, разрешенных к применению только в конструкциях макроязыка.

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...