Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсач гофаров 5 вариант.doc
Скачиваний:
19
Добавлен:
03.05.2019
Размер:
609 Кб
Скачать
☆
      1. Irpc-блоки

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

IRPC р,s1...sk

<тело>

ENDM

И здесь р - формальный параметр, а вот si- это символы. Это могут быть любые символы, кроме пробелов и точек с запятой (считается, что с точки с запятой начинается комментарий, а пробел заканчивает операнд; если надо указать точку с запятой или пробел, то всю последовательность символов следует заключить в угловые скобки - см. разд. 2.4). Встречая IRPC-блок, макро­генератор заменяет его на k копий тела блока (по одной на каждый символ), причем в i-й копии все вхождения пар-ра р будут заменены на символ si.

Пример:

IRPC D,17W ADD AX,1

ADD AX,D  ADD AX,7

ENDM ADD AX,W

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

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

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

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

IRP W, <VAR1,VAR6> VAR1 DW ?

W DW ?  VAR6 DW ?

ENDM Здесь параметр W обозначает имя переменной целиком. Но фактические имена (VAR1 и VAR6) различаются лишь последним символом, поэтому было бы разум­нее объявить параметром только этот символ, а не все имя. Но если так и сделать:

IRP W,<1 , 6>

VARW DW ?

ENDM

то получится неоднозначность: становится непонятным, когда W обозначает формальный параметр, а когда саму букву W (почему в VARW надо W заменять на 1 и 6, а в DW не надо?). Во всех предыдущих примерах мы не сталкивались с такой проблемой, т. к. формальные параметры легко выделялись из окружаю­щего текста благодаря ограничителям (пробелам, запятым и т. п.), стоящим слева и справа от них. Но если рядом с параметром стоит имя или число, то границы параметра становятся неопределяемыми. В подобной ситуации следует между параметром и соседним с ним числом или именем поставить символ & (А&W, 1&W&В и т. п.). Например, наш блок повторения должен быть записан следующим образом:

IRP W ,<1 , 6>

VAR&W DW ?

ENDM

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

IRPC A,”< DB ‘A, “, “B’

DB ‘A, &A, &A&В'  DВ 'А, < , < В'

ENDM

И ещё одна особенность макрооператора &: если рядом поставить несколько знаков &, то макрогенератор удалит только один из них. Это сделано специально, учитывая возможность вложенности блоков повторений (и/или макросов). Например:

IRPC P1,AB IRPC P2,HL INC AH

IRPC P2,HL  INC A&P2  INC AL

INC P1&&P2 ENDM INC BH

ENDM IRPC P2,HL INC BL

ENDM INC B&P2

ENDM

Встретив в тексте исходной программы блок повторения, указанный в левой колонке, макрогенератор сначала создаст первую копию тела внешнего блока, в котором все вхождения его формального параметра Р1 будут заменены на символ А (см. три верхние строчки средней колонки). При этом из двух подряд стоящих в команде INC знаков & будет удален только один, и оставшийся знак & будет отделять формальный параметр Р2 внутреннего блока от стоящей слева буквы А (если бы был только один знак &, то эта команда имела бы вид INC АР2, и потому запись АР2 не воспринималась бы как состоящая из двух частей - А и Р2). Поскольку в полученной копии остались конструкции макроязыка, то макрогенератор продолжает свою работу (это общее правило: макрогенератор работает, пока не получится текст на "чистом" языке ассемблера) и "раскручивает" внутренний блок, получая уже окончательный текст (см. две верхние строчки в правой колонке). Далее создается вторая копия внешнего блока, которая обрабатывается аналогично.

Макрооператор <>

Как было сказано, фактические параметры IRP-блока не должны содержать запятые, точки с запятой и уголки, а во втором операнде IRРС-блока нельзя указывать пробелы и точки с запятой. Эти ограничения связаны с тем, что иначе возможна путаница: например, если внутри фактического параметра IRР-блока указать запятую (скажем: 1,2), тогда будет непонятным, что означает эта запись- то ли два параметра, разделенных запятой, то ли один параметр. Так вот, если надо нарушить указанные ограничения, тогда весь фактический параметр IRР-блока или всю последовательность символов в IRРС-блоке надо заключить в угловые скобки (например: <1,2>), причем текст внутри этих скобок должен быть сбалансирован по уголкам. При этом считается, что внешние угловые скобки не относятся к параметру или последовательности, что они лишь указывают их границы.

Примеры:

IRP VAL, <<1 , 2> , 3>  DB 1 , 2

DB VAL DB 3

ENDM

IRPC S, <A ; B>  DB ‘A’

DB ‘&S’ DB ‘;’

ENDM DB ‘B’

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

А что делать, если внутри фактического параметра надо указать непарный уголок или кавычку? Для задания этих и других спецсимволов (вне или внутри угловых скобок) предусмотрен следующий макрооператор:

!<символ>

Смысл этой записи: сам символ ! "погибает" (не переносится в окончательный текст); но следующий за ним символ трактуется как обычный символ, а не как символ, играющий какую-то специальную роль. Например:

IRP X, <A!>B, Привет ! , ПК !!> DB ‘A>B’

DB ‘&X’  DB ‘Привет, ПК !’

ENDM

Макрооператор ! можно использовать только при записи фактических параметров IRP-блоков (и макросов), тогда как в последовательности символов (во втором операнде) IRРС-блока знак ! рассматривается как обычный символ. Указывать в этой последовательности уголки можно сколько угодно раз, если эта последовательность не начинается с открывающей угловой скобки, а если начинается - пока нет баланса угловых скобок.

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

В макроязыке есть еще один макрооператор, используемый при записи фактических параметров IRP-блоков (и макросов):

% <константное выражение>

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

K EQU 4

. . . DW K+1

IRP А,<К+1,%К+1,W%К+1>  DW 5

DW A DW W5

ENDM

Отметим, что вложенность макрооператоров % не допускается (например, в конструкции %5-%К будет зафиксирована ошибка "неописанное имя %К") и что концом константного выражения считается первый символ (например, запятая, угловая скобка или знак равенства), который не может по синтаксису входить в константные выражения (например, при значении 4 у константы К параметр %К-1+К=К будет преобразован в 7=К).

Отметим также, что в последовательности символов (во втором операнде) IRPC-блока знак % рассматривается как обычный символ, а не как макрооператор.

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

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

IRР R,<АХ,ВХ> ;восстановить АХ

;;восстановление регистров POP AX

;восстановить R  ; восстановить ВХ

РОР R ;;стек ==> R POP BX

ЕNDМ