Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 150

Unknown Author

ENDIF

MOV AL,BH

MOV AL,BH

??0105:

??0105:

ENDIF

Как уже отмечалось, при сравнении текстов в директивах IFIDN и IFDTF большие и малые буквы не отождествляются. Это неприятная особенность данных директив. Обычно с их помощью в макросах сравниваются имена переменных и регистров, а эти имена в текстах программ могут записываться как малыми, так и большими буквами или вперемежку, и если при обращении к макросу имена записаны не теми буквами, как предусмотрел автор макроса, то -тот макрос может сформировать неправильное макрорасширение. Например, по маг г окоманде ММ AL,AH,Max будет построена группа команд для вычисления минимума (!) чисел из регистров AL и АН, т. к. в теле макроса ММ директива IFIDN будет сравнивать тексты Мах и МАХ, которые не совпадают.

Как преодолеть этот недостаток? Можно предложить следующий метод: берем все возможные варианты записи имени (например, АН, Ah, аН и ah) и с помощью IRP-блока и директивы IFIDN проверяем, не совпадает ли заданное имя с одним из этих вариантов; если совпадает, тогда некоторому вспомогательному имени с помощью директивы присваивания (=) даем одно значение, не совпадает - другое; затем это значение нужно проверить директивой IF.

Эти действия (кроме последней проверки) можно описать в виде следующего макроса SAME N,LN,F (где N - то, что проверяем; LN - список (в уголках, через запятую) всех возможных вариантов записи имени, для которого делаем проверку; F - имя, которому присваивается результат проверки: -1 (истина) - есть совпадение, 0 - нет):

SAME MACRO N,LN,F

;присвоить 0 имени F (на случай несовпадения) ;для каждого варианта V из LN выполнить:

;если V совпал с N, то ; переприсвоить F значение -1 ; прекратить макроподстановку

F=0

IRP V,<LN>

IFIDN <V>,<N>

F=-l EXITM END IF ENDM ENDM

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

SAME Ah,<AH,Ah,aH,ah>,AX?    —S    АХ?=0

АХ?=-1

SAME bh, <АН , Ah, аН, ah>, AX'?    АХ?=0

Используем SAME для описания в виде макроса CALL_P X команд обращения к процедуре Р, параметр (X) для которой передается через регистр АХ.

В общем случае этот макрос должен обозначать следующие команды:

HOV АХ,X

call р

Однако, если в качестве X указан регистр АХ, то первая команда не нужна. Таким образом, здесь надо сравнивать X с именем АХ, причем с любым из возможных вариантов его записи. Для этого мы и воспользуемся макросом SAME, причем имя, которому присваивается результат проверки, локализуем в макросе

CALL Р:

CALL_P MACRO X

LOCAL F

SAME X,<AX,Ax,aX,ax>,F    ;;FистинаM, если X - это AX

IFE F    ;;если F - "ложь", то

MOV AX,X    ;;сформировать команду AX: -X

END IF

CALL P

ENDM

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

IFB <t>

IFNB <t>

Они фактически являются вариантами директив IFIDN и IFDIF, когда второй текст пуст. В директиве IFB (if blank, если пусто) условие считается выполненным, если текст t пуст, а в директиве IFNB (if not blank) - если текст t не пуст.

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