Переопределение и отмена макросов 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Переопределение и отмена макросов



В отличие от других объектов программы на ЯА, макросы можно пере­определить или уничтожить. Если в тексте программы описать макрос с именем, которым ранее был обозначен другой макрос, то с этого момента прежний макрос считается уничтоженным, а новый макрос - действующим. Например:

A MACRO X

INC X

ENDM

A CX à INC CX

A MACRO Y,Z

CMP Y, 0

JE Z

ENDM

A BH, EQ à CMP BH,0

JE EQ

Макрос можно и просто уничтожить, не определяя новый макрос с тем же именем, для чего надо воспользоваться следующей директивой:

РURGE <имя макроса> {,<имя макроса>}

После этой директивы все макросы, имена которых в ней перечислены, считаются несуществующими. Например, после директивы

PURGE A, ININT

к макросам А и ININТ уже нельзя обращаться.

 

Условное ассемблирование

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

< IF –директива> < IF –директива>

<фрагмент-1> или <фрагмент-1>

ELSE ENDIF

<фрагмент-2>

ENDIF

Директивы ELSE и ENDIF обязательно должны записываться в отдельных строчках. В каждом же фрагменте может быть любое число любых предложений, в частности в них может быть IF-блоки, т.е. допускается вложенность IF-блоков. В IF-директиве (имеется несколько разновидностей ее) указывается некоторое условие, которое проверяется макрогенератором. Если условие выполнено, то макрогенератор оставляет в окончательном тексте программы только фрагмент 1, а фрагмент -2 исключает, не переносит в окончательный текст. Если же условие не выполнено, то все наоборот. Если части ELSE нет, то считается, что фрагмент-2 пуст, поэтому при не выполнении условия такой IF- блок ничего не «поставляет» в окончательный текст программы. Поскольку условие в IF-директиве проверяется на этапе макрогенерации, то вполне естественно, в нем не должно быть ссылок на величины,которые станут известными только при выполнении программы (например, в условии нельзя ссылаться на содержимое регистров или ячеек памяти). Более того, условие должно быть таким, чтобы макрогенератор мог вычислить его сразу, как только встретит его (например, в нем не должно быть ссылок вперед).

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

 

Директивы IF и IFE

Эти директивы имеют следующий вид:

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

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

Встречая любую из этих директив, макрогенератор вычисляет указанное к ней константное выражение. В директиве IF условие считается вычисленным, если значение выражения отлично от 0, а директиве IFE (if equal, если равно) – если значение равно 0. Рассмотрим следующий пример. Предположим, что мы отлаживаем программу и для этого вставляем в определенные места ее текста отладочные печати (ОП), т.е. печать промежуточных значений каких-то переменных. Закончив отладку, мы, естественно, убираем ОП из текста. Но может оказаться так, и это действительно часто случается, что затем в программе опять появятся ошибки, и чтобы их найти, нам придется вставить те же ОП, а после исправления ошибок - снова удалить. И этот процесс вставки и удаления ОП может продолжаться долго. Вставлять и убирать ОП мы можем, конечно, сами с помощью какого-нибудь текстового редактора. Но если ОП много, если они разбросаны по всей программе, то такие изменения текста займут много времени, а кроме того, здесь легко и ошибиться – мы можем не туда вставить ОП или можем убрать из текста не то, что надо. Так вот, в подобной ситуации как раз и удобно использовать возможности условного ассемблирования: в тексте программы постоянно сохраняем ОП, но перед каждой из них указываем условие, что команды ОП должны оставаться в окончательном тексте программы только при отладке. Конкретно это можно сделать так. Договоримся, что режим прогона программы (отладка или счет) указывается с помощью константы DEBUG (отладка), которую описываем в начале текста программы и которой присваиваем значение 1, если у нас сейчас отладка:

DEBUG EQU 1

или значение 0 при счете:

DEBUG EQU 0

Тогда участок исходной программы с отладочной печатью (скажем, переменной Х) должен быть записан так, как указанно слева, в окончательном же тексте программы этот участок будет выглядеть так, как изображено справа:

...

... DEBUG<>0 MOV X, AX

MOV X, AX ─────────> OUTINT X

IF DEBUG MOV BX, 0

OUTINT X ...

ENDIF

MOV BX,0 DEBUG=0 ...

... ─────────> MOV X, AX

MOV BX, 0

...

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

...

MOV X, AX

CMP отладка?

JNE L

OUTINT X

L: MOV BX,0

...

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

Рассмотрим еще один пример на использование директив IF и IFЕ, в котором средства условного ассемблирования используются не самостоятельно, как в предыдущем примере, а для описания макросов, что является основным случаем применения этих средств.

Опишем в виде макроса SHIFT Х,N операцию сдвига Х на N разрядов вправо при условии, что параметр Х - это имя какой-то переменной, а N - явно заданное положительное число, и при условии, что макрорасширение этого макроса должно содержать минимально возможное число команд.

Последнее условие означает, что по макрокоманде SHIFT X,N при N=1 должно формироваться макрорасширение из одной команды (SНR Х,1), а при N>1 - из двух команд (МОV CL,N и SHR Х,СL). Поскольку здесь в зависимости от некоторого условия (величины N) в окончательный текст программы (в макро­расширение) должны попадать разные фрагменты, то ясно, что при описании макроса следует воспользоваться средствами условного ассемблирования. Сделать это можно, например, так:

SHIFT MACRO X,N

IFE N-1;; N-1=0? (N=1?)

SHR X,1

ELSE;;N>1

MOV CL,N

SHR X,CL

ENDIF

ENDM

Ниже для примера показано,как осуществляется макроподстановка для макрокоманды

SHIFT А, 5:

X→A, N→5 IFE 5-1 5-1=0? MOV CL,5

SHIFT A,5 ────────> SHR A,1 ─────> SHR A,CL

ELSE нет

MOV CL,5

SHR A,CL

ENDIF



Поделиться:


Последнее изменение этой страницы: 2016-12-13; просмотров: 171; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.82.167 (0.009 с.)