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



ЗНАЕТЕ ЛИ ВЫ?

Директивы ifidn ,ifdif , ifb и ifnb

Поиск

Вернемся к IF-дирeктивам и следующей рассмотрим такую пару директив:

IFIDN < t1 >,< t2 >

IFDIF <t1>,<t2>

Здесь t1 и t2 - любые тексты (последовательности символов), причем они обязательно должны быть заключены в уголки. Эта тексты посимвольно сравниваются. В директиве IFIDN условие считается выполненным, если эти тексты равны (идентичны, identical), а в директиве IFDIF - если они не равны (различны, different). Отметим, что при сравнении этих текстов большие и малые буквы не отождествляются. Примеры:

IFDIF <a+b>,<a+b> -условие выполнено

IFDIF <a+b>,<a> -условие не выполнено

IFDIF <a+b>,<a+B> -условие не выполнено

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

В качестве примера опишем в виде макроса ММ R1,R2,Т (где R1 и R2 - имена байтовых регистров, содержимое которых трактуется как знаковые числа, а Т -слово МАХ или МIN операцию R1: = Т(R1,R2), т. е, запись в R1 либо максимума чисел R1 и R2 (при Т=МАХ), либо минимума. Прежде всего отметим, что этот макрос должен генерировать непустое макрорасширение, только если R1 и R2 - разные регистры (при обращении же, скажем, ММ АL,АL,МАХ менять значение АL не надо). Как проверить несовпадение двух первых фактических параметров макроса? Отметим, что директива IF R1 NE R2 здесь не проходит,

т. к. оператор NE предназначен для сравнения чисел, а нам надо сравнить имена регистров. Зато здесь проходит директива IFDIF <R1>,<R2>, в которой при макроподстановке формальные параметры R1 и R2 будут заменены на имена регистров (для указанной выше макрокоманды эта директива примет вид IFIDN <АL>,<АL>), что и позволит сравнить эти имена. Далее. Чтобы определить, что именно надо вычислять - максимум или минимум, надо проверить третий фактический параметр: МАХ это или МIN? Сделать это можно, например, с помощью директивы IFIDN <T>, <МАХ>: при макроподстановке формальный параметр Т будет заменен на третий фактический параметр, который тем самым и будет сравниваться со словом МАХ. И последнее. Вычисления максимума и минимума различаются лишь одной командой - командой условного перехода:

;R1:=max (R1,R2); R1:=min(R1,R2)

CMP R1,R2 CMP R1,R2

JGE L JLE L

MOV R1,R2 MOV R1,R2

L: L:

поэтому не имеет смысла в макроопределении дважды выписывать эту практически одинаковую группу команд, а достаточно выписать ее лишь раз, поместив вместо команды условного перехода IF-блок, который в зависимости от параметра Т выберет нужную команду условного перехода. С учетом всего сказанного получаем такое описание макроса ММ:

MM MACRO R1,R2 T

LOCAL L

IFDIF <R1>,<R2>;;R1 и R2 – разные регистры

CMP R1,R2

IFIDN <T>,<MAX>;; T=MAX?

JGE L;;да – поместить JGE L в макрорасширение

ELSE

JLE L;; нет поместить JLE L

ENDIF

MOV R1,R2

L:

ENDIF

ENDM

Приведем этапы макроподстановки для макрокоманды ММ AL,BH,MIN после того, как в теле макроса формальные параметры были заменены на фактические параметры, а локальная метка L - на специмя (скажем,??0105):

 

IFDIF <AL>,<BH>

CMP AL,BH CMP AL,BH CMP AL,BH

IFIDN <MIN>,<MAX> IFIDN <MIN>,<MAX> JLE??0105

JGE??0105 ────à JGE??0105 ────à MOV AL,BH

ELSE ELSE??0105:

JLE??0105 JLE??0105

ENDIF ENDIF

MOV AL,BH MOV AL, BH

??0105:??0105:

ENDIF

Как уже отмечалось, при сравнении текстов в директивах IFIDN и IFDIF большие и малые буквы не отождествляются. Это неприятная особенность дан­ных директив. Обычно сих помощью в макросах сравниваются имена переменных и регистров, а эти имена в текстах программ могут записываться как малыми, так и большими буквами или вперемежку, и если при обращении к макросу имена записаны не теми буквами, как предусмотрел автор макроса, то - тот макрос может сформировать неправильное макрорасширение. Например, по макракоманде ММ АL,АН,Мах будет построена группа команд для вычисления минимума (!) чисел из регистров АL и АН, т. к. в теле макроса ММ директива IFIDN будет сравнивать тексты Мах и МАХ, которые не совпадают. Как преодолеть этот недостаток? Можно предложить следующий метод: берем все возможные варианты записи имени (например, АН, АL, аН и аL) и с по­мощью IRР-блока и директивы IFIDN проверяем, не совпадает ли заданное имя с одним из этих вариантов; если совпадает, тогда некоторому вспомогательному имени с помощью директивы присваивания (=) даем одно значение, не совпада­ет - другое; затем это значение нужно проверить директивой IF. Эти действия (кроме последней проверки) можно описать в виде следующего макроса SAME N,LN,F (где N - то, что проверяем; LN - список (в уголках, через запятую) всех возможных вариантов записи имени, для которого делаем проверку; F - имя, которому присваивается результат проверки: -1 (истина) - есть совпадение, 0 - нет):

SAME MACRO N,LN,F

F=0;;присвоить 0 имени F (на случай несовпадения)

IRP V,<LN>;; для каждого варианта V из LN выполнить:

IFIDN <V>,<N>;; если V совпал с N, то

F = -1;;перепресвоить F значение -1

EXITM;;прекратить макроподстановку

ENDIF

ENDM

ENDM

Хотя макроподстановка для этого макроса может выполняться достаточно долго, в конце концов генерируется либо одна, либо две директивы присва­ивания, например:

SАМЕ АH,<АН,Аh,аН,аh>,АХ? à АХ?=0

АХ?= -1

SАМЕ bh,<АН,Аh,аН,аh>,АХ? à АХ?=0

Используем SАМЕ для описания в виде макроса САLL_Р Х команд обращения к процедуре Р, параметр (X) для которой передается через регистр АХ. В общем случае этот макрос должен обозначать следующие команды:

MOV AX,X

CALL P

Однако, если в качестве Х указан регистр АХ, то первая команда не нужна. Таким образом, здесь надо сравнивать Х с именем АХ, причем с любым из возможных вариантов его записи. Для этого мы и воспользуемся макросом SАМЕ, причем имя, которому присваивается результат проверки, локализуем в макросе СALL_Р:

CALL_P MACRO X

LOCAL F

SAME X,<AX,Ax,aX,ax>,F

IFE F

MOV AX,X

ENDIF

CALL P

ENDM

Теперь рассмотрим еще две IF-директивы:

IFВ <t>

IFNB <t>

Они фактически являются вариантами директив IFIDN и IFDIF, когда второй текст пуст. В директиве IFВ (if blank, если пусто) условие считается выполненным, если текст t пуст, а в директиве IFNВ (if not blank)- если текст t не пуст. Эти директивы используются в макросах для проверки, задан ли фактический; параметр или нет (не задать параметр - значит указать в соответствующей позиции макрокоманды пустой текст). Например, макроопределение

DEF MACRO X, V

IFB <V>;параметр V не задан (пустой)?

X DB?

ELSE

X DB V

ENDIF

ENDM

описывает макрос DEF Х,N, по которому определяется байтовая переменная Х с начальным значением V, если оно указано, или без него:

DEF A,6 ─────> A DB 6

DEF B ─────> B DB?



Поделиться:


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

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