Читать «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?
АХ?=-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 не пуст.
Эти директивы используются в макросах для проверки, задан ли фактический параметр или нет (не задать параметр - значит указать в соответствующей позиции макрокоманды пустой текст). Например, макроопределение