assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 70
Текст из файла (страница 70)
a xexit:mov ax,4c00hint 21hend mainЗапустив этот пример на трансляцию, вы получите сообщение о том, что забыли определить значение переменной size_m. Исправить эту ошибку можно однимиз двух способов:Директивы условной компиляции313ii в начале исходного текста программы определите значение этой переменнойс помощью псевдооператоа EQU:size_m equ 15ii запустите программу на трансляцию командной строкой видаtasm /dsize_m=15 /zi prg_13_2,,,В листинге 14.5 мы использовали еще одну возможность транслятора — директиву DISPLAY, с помощью которой можно формировать пользовательское сообщение в процессе трансляции программы. Директива DISPLAY будет рассмотренав конце данной главы.Директивы IFB и IFNBСинтаксис директив IFB и IFNB следующий:IF(N)B аргументфрагмент_программы_1ELSEфрагмент_программы_2ENDIFДанные директивы используются для проверки фактических параметров, передаваемых в макрос.
При вызове макрокоманды они анализируют значение аргумента и в зависимости от того, равно оно пробелу или нет, транслируется либопервый фрагмент программы (фрагмент_программы_1), либо второй (фрагмент_программы_2). Какой именно фрагмент будет выбран, зависит от кода директивы.« Директива IFB проверяет равенство аргумента пробелу.
В качестве аргументамогут выступать имя или число. Если его значение равно пробелу (то есть фактический аргумент при вызове макрокоманды не был задан), то транслируетсяи помещается в объектный модуль первый фрагмент программы. В противномслучае при наличии директивы ELSE в объектный код помещается второй фрагмент программы.
Если же директивы ELSE нет, то при равенстве аргумента пробелу вся часть программы между директивами IFB и ЕШ1Еигнорируется и в объектный модуль не включается.ж Действие IFNB обратно действию IFB. Если значение аргумента в программе неравно пробелу, то транслируется первый фрагмент программы. В противномслучае при наличии директивы ELSE в объектный код помещается второй фрагмент программы. Если же директивы ELSE нет, то вся часть программы (принеравенстве аргумента пробелу) между директивами IFNB и ENDIF игнорируется и в объектный модуль не включается.Типичным примером применения этих директив являются строки в макроопределении, проверяющие, указывается ли фактический аргумент при вызове соответствующей макрокоманды:showmacroifb <reg>regdisplay "не задан регистр"exi tmendifendm314Глава 14. Макросредства языка ассемблераЕсли теперь в сегменте кода вызвать макрос SHOW без аргументов, то будет выведено сообщение о том, что не задан регистр, и генерация макрорасширения прекратится директивой EXITM.Директивы IFIDN, IFIDNI, IFDIF и IFDIFIДирективы IFIDN, IFIDNI, IFDIF и IFDIFI позволяют не просто проверить наличие илизначения аргументов макрокоманды, но и выполнить идентификацию аргументовкак строк символов.
Синтаксис этих директив:IFIDN(I)аргумент_1,аргумент_2фрагмент_программы_1ELSEфрагмент_программы_2ENDIFIFDIF(I)аргумент_1,аргумент_2фрагмент_программы_1ELSEфрагмент_программы_2ENDIFВ этих директивах проверяются аргумент_1 и аргумент_2 как строки символов.Какой именно код (фрагмент_программы_1 или фрагмент_программы_2) будет транслироваться по результатам сравнения, зависит от кода директивы. Наличие двухпар этих директив объясняется тем, что они позволяют учитывать либо не учитывать различие строчных и прописных букв. Так, директивы IFIDNI и IFDIFI игнорируют это различие, a IFIDN и IFDIF — учитывают.i» Директива IFIDN(I) сравнивает символьные значения аргумент_1 и аргумент_2.Если результат сравнения положительный, то транслируется и помещаетсяв объектный модуль первый фрагмент программы. В противном случае при наличии директивы ELSE, в объектный код помещается второй фрагмент программы.
Если же директивы ELSE нет, то вся часть программы между директивамиIFIDN(I) и ENDIF игнорируется и в объектный модуль не включается.s Действие IFDIF(I) обратно действию IFIDN(I). Если результат сравнения отрицательный (строки не совпадают), транслируется первый фрагмент программы. В противном случае все происходит аналогично рассмотренным ранее директивам.Как мы уже упоминали ранее, эти директивы удобно применять для проверкифактических аргументов макрокоманд. К примеру, проверим, какой из регистров —al или ah — передан в макрос в качестве параметра (проверка проводится без учетаразличия строчных и прописных букв):showmacrorifdifi <al> , <rg>gotoM_alelseifdifi <ah>, <rg>M_ahgotoelseexi tmendifendif:H alДирективы условной компиляции315:M_ahendmВложенность директив условной трансляцииКак мы неоднократно видели в приведенных ранее примерах, транслятор Т ASMдопускает вложенность условных директив компиляции.
Более того, так как вложенность требуется довольно часто, TASM предоставляет набор дополнительныхдиректив формата ELSEIFxxx, которые заменяют последовательность идущих подряд директив ELSE и IFxxx в структуреIFxxxELSEIFxxxENDIFENDIFЭту последовательность условных директив можно заменить эквивалентнойпоследовательностью дополнительных директивIFxxxELSEIFxxxENDIFСимволы ххх в ELSExxx говорят о том, что каждая из директив — IF, IFB, IFIDNи т.
д. — имеет соответствующую директиву ELSEIF, ELSEIFB, ELSEIFIDN и т. д. В конечном итоге это улучшает читабельность кода. В последнем примере фрагментамакроса, проверяющем, имя какого регистра было передано в макрос, наблюдается подобная ситуация. Последовательности ELSE и IFDIFI можно записать так, какв строке 4:<1> showmacro rg<2> ifdifi <al>,<rg><3> goto M_al<4><S><6><7><8><9>else ifdifi <ah>,<rg>goto M_ahelseexitmendif:M_al:M_ah<13>endmДирективы генерации ошибокВ языке TASM есть ряд директив, называемых директивами генерации пользовательской ошибки.
Их можно рассматривать и как самостоятельное средство, и какметод, расширяющий возможности директив условной компиляции. Они предназначены для обнаружения различных ошибок в программе, таких как неопределенные метки или пропуск параметров макроса. Директивы генерации пользовательской ошибки по принципу работы можно разделить на два типа:Я безусловные директивы генерируют ошибку трансляции без проверки какихлибо условий;316Глава 14. Макросредства языка ассемблераit условные директивы генерируют ошибку трансляции после проверки определенных условий.Большинство директив генерации ошибок имеет два обозначения, хотя принцип их работы одинаков.
Второе название отражает их сходство с директивамиусловной компиляции. При дальнейшем обсуждении такие парные директивыбудут приводиться в скобках. •Безусловная генерация пользовательской ошибкиК директивам безусловной генерации пользовательской ошибки относится только одна директива ERR (.ERR).Данная директива, будучи вставлена в текст программы, безусловно приводитк генерации ошибки на этапе трансляции и удалению объектного модуля.
Она оченьполезна при использовании с директивами условной компиляции и при включении в тело макрокоманды с целью отладки. К примеру, эту директиву можно былобы вставить в ту ветвь программы (в последнем рассмотренном нами макроопределении), которая выполняется, если указанный в качестве аргумента регистр отличен от al и ah:macro rgshowifdifigotoM_al'elseifdifi <ah>,<rg>M_ahgotoelse.ErrendifendifendmЕсли после определенного таким образом макроопределения в сегменте кодавызвать макрокоманду show с фактическим параметром, отличным от имен регистров ah или al, будет сгенерирована ошибка компиляции (с текстом «User error»),сам процесс компиляции прекращен и, естественно, объектный модуль создан небудет.Остальные директивы являются условными, так как их поведение определяютнекоторые условия.Условная генерация пользовательской ошибкиНабор условий, на которые реагируют директивы условной генерации пользовательской ошибки, такой же, как и у директив условной компиляции.
Поэтому и количество этих директив такое же. Принцип их работы ясен, поэтому рассматривать их мы будем очень кратко. Заметим только, что использовать большинстводиректив условной генерации пользовательской ошибки, как и директив условной компиляции, можно и в макроопределениях, и в любых местах программы.Директивы .ERRB (ERRIFB) и .ERRNB (ERRIFNB)Синтаксис директив .ERRB (ERRIFB) и .ERRNB (ERRIFNB):.ERRB (ERRIFB) <имя_формального_аргумента>.ERRNB (ERRIFNB) <имя_формального_аргумента>Директивы условной компиляции317ж Директива .ERRB (ERRIFB) вызывает генерацию пользовательской ошибки, еслиформальный аргумент с именем <имя_формального_аргумента> пропущен.• Директива .ERRNB (ERRIFNB) вызывает генерацию пользовательской ошибки, еслиформальный аргумент с именем <имя_формального_аргумента> присутствует.Данные директивы применяются для генерации ошибки трансляции в зависимости от того, задан или нет при вызове макрокоманды фактический аргумент,соответствующий формальному аргументу в заголовке макроопределения с именем <имя_формального_аргумента>.
По принципу действия эти директивы полностьюаналогичны соответствующим директивам условной компиляции IFB и IFNB. Ихобычно используют для проверки задания параметров при вызове макроса. Строка, являющаяся именем формального аргумента, должна быть заключена в угловыескобки.К примеру, определим обязательность задания фактического аргумента, соответствующего формальному аргументу rg, в макросе show:<1>showmacro rg<2>;если rg в макрокоманде не будет задан,<3>;то завершить компиляцию<4>.errb<rg><5>;текст макроопределения<б>;...<7>endtnДирективы .ERRDEF (ERRIFDEF) и .ERRNDEF (ERRIFNDEF)Синтаксис директив .ERRDEF (ERRIFDEF) и .ERRNDEF (ERRIFNDEF):.ERRDEF (ERRIFDEF) символическое_имя.ERRNDEF (ERRIFNDEF) символическое_имяи Директива .ERRDEF (ERRIFDEF) генерирует пользовательскую ошибку, если указанное символическое имя определено до выдачи этой директивы в программе.li Директива .ERRNDEF (ERRIFNDEF) генерирует пользовательскую ошибку, еслиуказанное символическое имя не определено до момента обработки транслятором этой директивы.Данные директивы генерируют ошибку трансляции в зависимости от того, определено или нет некоторое символическое имя в программе.
Не забывайте о том,что компилятор TASM по умолчанию формирует объектный модуль за один проход исходного текста программы. Следовательно, директивы .ERRDEF (ERRIFDEF)H.ERRNDEF(ERRIFNDEF) отслеживают факт определения символического имени только в той части исходного текста, которая находится до этих директив.Директивы .ERRDIF (ERRIFDIF) и .ERRIDN (ERRIFIDN)Синтаксис директив .ERRDIF (ERRIFDIF) и .ERRIDN (ERRIFIDN):.ERRDIF (ERRIFDIF) <строка_1>,<строка_2>.ERRIDN (ERRIFIDN) <строка_1>,<строка_2>Ш Директива .ERRDIF (ERRIFDIF) генерирует пользовательскую ошибку, если двестроки посимвольно не совпадают.