<<
>>

Макрокоманды

По смыслу макрокоманда представляет собой дальнейшее развитие механизма замены текста. С помощью макрокоманд в текст программы можно вставлять по- следовательности строк (которые логически могут быть данными или командами) и даже более того — привязывать их к контексту места вставки.
Представим ситуацию, когда необходимо выполнить некоторые повторяющи- еся действия. Механизм макрокоманд предоставляет возможность заменить оди- наковые участки кода одной строкой, а первоначальный исходный текст описать один раз в определенном месте программы или во внешнем файле. Дальнейшее наше обсуждение будет посвящено тому, как это сделать. Определимся с терминологией. Осмысленное рассмотрение данного механиз- ма предполагает понимание смысла терминов макрокоманда и макроопределение. Макрокоманда представляет собой строку, одним из компонентов которой явля- ется символическое имя макрокоманды. Имя макрокоманды может сопровождать- ся параметрами. Если данная строка встречается в теле исходного текста програм- мы, то транслятор замещает ее одной или несколькими другими строками.
Какими именно строками — определяется макроопределением, которое представляет собой шаблон (описание) макрокоманды. Таким образом, для использования макрокоманды в программе первым делом задают ее макроопределение. Синтаксис макроопределения следующий: имя_макрокоманды macro список_формальных_арrументов тело макроопределения еrtdm Где должны располагаться макроопределения? Есть три варианта. Ш Макроопределения могут располагаться в начале исходного текста программы до сегмента кода и данных с тем, чтобы не ухудшать читабельность программы. Этот вариант следует применять в случаях, если определяемые вами макроко- манды актуальны только в пределах одной этой программы. * Макроопределения могут располагаться в отдельном файле.
Этот вариант под- ходит при работе над несколькими программами одной проблемной области. Чтобы сделать доступными эти макроопределения в конкретной программе, необходимо в начале исходного текста этой программы записать директиву include имя_файла, к примеру: mаsm model small i nclude show. i nc ;в это место будет вставлен текст файла shоw.iпс Макроопределения могут располагаться в макробиблиотеке. Если у вас есть универсальные макрокоманды, которые используются практически во всех ва- ших программах, то их целесообразно записать в так называемую макробиблио- теку. Сделать актуальными макрокоманды из этой библиотеки можно с по- мощью все той же директивы INCLUDE. Недостаток этого и предыдущего способов — в том, что в исходный текст программы включаются абсолютно все макроопре- деления. Для исправления ситуации можно задействовать директиву PURGE, в качестве операндов которой через запятую перечисляются имена макроко- манд, которые не должны включаться в текст программы. К примеру, include i оmас . i пс purge оutstr,ехit В данном случае в исходный текст программы перед началом компиляции транс- лятор TASM вместо строки include iomac.inc вставит строки из файла iоmас.iпс, отличающиеся от оригинала тем, что в этих строках будут отсутствовать мак- роопределения ОUТSТR и EXIT.

А теперь вернемся к главе б и вспомним программу из листинга 6.1. Проанали- зируем ее текст, выявим повторяющиеся участки и составим для них макроопре- деления (листинг 14.1).

В листинге 14.1 в строках 2-7, 8-16,18-21, 23-28, 30-37, 39-43 описаны мак- роопределения. Описание их назначения приведено сразу после заголовка в теле каждого макроопределения.

Если вынести эти макроопределения в отдельный файл, то впоследствии можно использовать их при написании других программ. Посмотрите на модернизированный исходный текст программы из листинга 6.1 в листинге 14.1 (строки 54-68). Если не обращать внимания на некоторые неяс- ные моменты, то сам сегмент кода стал внешне более читабельным, и даже можно сказать, что в его новых командах появился какой-то смысл. Откомпилируйте ли- стинг 14.1 и получите файл листинга. После этого сравните текст программы до и после обработки ассемблером. Вы увидите, что исходный текст изменился, — пос- ле строк программы, в которых были макрокоманды, появились фрагменты тек- ста. Содержимое этих фрагментов определяется содержимым макроопределений (шаблонов), заданных в начале программы. Видно, что путем ввода параметров для макрокоманды можно модернизировать содержимое фактического текста, за- мещающего макрокоманду. Функционально макроопределения похожи на процедуры. Сходство в том, что и те, и другие достаточно один раз где-то описать, а затем вызывать их специаль- ным образом. На этом сходство заканчивается и начинаются различия, которые в зависимости от целевой установки можно рассматривать и как достоинства, и как недостатки. * В отличие от процедуры, текст которой неизменен, макроопределение в про- цессе макрогенерации может меняться в соответствии с набором фактических параметров. При этом коррекции могут подвергаться как операнды команд, так и сами команды. Процедуры в этом отношении менее гибки. И При каждом вызове макрокоманды ее текст в виде макрорасширения вставля- ется в программу. При вызове процедуры процессор осуществляет передачу управления на начало процедуры, находящейся в некоторой области памяти в одном экземпляре. Код в этом случае получается более компактным, хотя быс- тродействие несколько снижается за счет необходимости осуществления пере- ходов. Макроопределение обрабатывается компилятором особым образом. Для того чтобы использовать описанное макроопределение, его нужно «активизировать» с помощью макрокоманды.
Для этого в нужном месте исходного кода программы на основе текста заголовка макроопределения указывается следующая синтакси- ческая конструкция: имя_макрокоманды список_фактических_аргументов В результате применения данной синтаксической конструкции соответствую- щая строка исходного текста программы заменяется строками из тела макроопре- деления. Но это не простая замена. Обычно макрокоманда содержит некоторый список аргументов (список_фактических_аргументов), которыми корректируется макроопределение. Места в теле макроопределения, которые будут замещаться фактическими аргументами из макрокоманды, обозначаются с помощью так на- зываемых формальных аргументов. Таким образом, в результате применения мак- рокоманды в программе формальные аргументы в макроопределении замещаются соответствующими фактическими аргументами; в этом и заключается учет кон- текста. Процесс такого замещения называется макрогенерацией, а результатом этого процесса является макрорасширение. К примеру, рассмотрим самое короткое макроопределение в листинге 14.1 — сlеаr_rg. Как отмечено ранее, результаты работы макроассемблера можно узнать, просмотрев файл листинга после трансляции. Покажем несколько его фрагмен- тов, которые демонстрируют, как был описан текст макроопределения сlеаr_rg (стро- ки 24-27), как был осуществлен вызов макрокоманды сlеаr_rg с фактическим па- раметром ах (строка 74) и как выглядит результат работы макрогенератора, сформировавшего команду ассемблера хоr ах,ах (строка 75): clear_r macro rg ;очистка регистра rg хоr rg,rg епdm сlеаr_r ах 00ΘΕ 33 С0 хоr ах,ах В итоге мы получили то, что и требовалось, — команду очистки заданного реги- стра, в данном случае АХ. В другом месте программы вы можете выдать ту же мак- рокоманду, но уже с другим именем регистра. Если у вас есть желание, можете провести эксперименты с этой и другими макрокомандами. Каждый фактический аргумент макрокоманды представляет собой строку символов, для формирования которой применяются определенные правила.
* Строка может состоять: ? из последовательности символов без пробелов, точек, запятых, точек с запя- той; ? из последовательности любых символов, заключенных в угловые скобки (), в которой можно указывать как пробелы, так и точки, запятые, точки с запятыми (мы упоминали об этом операторе выделения ассемблера при обсуждении директивы EQU). ® Для того чтобы указать, что некоторый символ внутри строки, представляю- щей фактический параметр, является собственно символом, а не чем-то иным, например, некоторым разделителем или ограничивающей скобкой, применя- ется специальный оператор !. Этот оператор ставится непосредственно перед нужным символом, и его действие эквивалентно заключению этого символа в угловые скобки. Таким образом, оператор ! также является оператором выде- ления, но одиночного символа. я Для вычисления в строке, представляющей фактический параметр в макроко- манде, некоторого константного выражения в начале этого выражения нужно поставить знак % (процент): % константное_выражение Значение константное_выражение вычисляется и подставляется в текстовом виде в соответствии с текущей системой счисления[13]. Теперь обсудим вопрос, как транслятор распознает формальные аргументы в те- ле макроопределения для их последующей замены фактическими аргументами? Прежде всего по их именам в заголовке макроопределения. В процессе генера- ции макрорасширения компилятор ассемблера ищет в тексте тела макроопределе- ния последовательности символов, совпадающие с теми последовательностями символов, из которых состоят формальные параметры. После обнаружения такого совпадения формальный параметр из тела макроопределения замещается соответ- ствующим фактическим параметром из макрокоманды. Этот процесс называется подстановкой аргументов. Здесь нужно отметить еще раз особо список формаль- ных аргументов в заголовке макроопределения. В общем случае он может содер- жать не только разделенные запятыми формальные элементы, но и некоторую до- полнительную информацию. Полный синтаксис формального аргумента следую- щий: ■ имя_формального_аргумента[:тип] Здесь тип может принимать значения: REQ — это значение говорит о том, что требуется обязательное явное задание фактического аргумента при вызове макрокоманды; т = — если аргумент при вызове макрокоманды не задан, то в соот- ветствующие места в макрорасширении по умолчанию будет вставлено значе- ние любая_строка (будьте внимательны: символы, входящие в операнд любая_ строка, должны быть заключены в угловые скобки).
Однако распознать в теле макроопределения формальный аргумент ассемблер может не всегда. Это, например, может не произойти в случае, когда он является частью некоторого идентификатора. В этом случае последовательность символов формального аргумента отделяют от остального контекста с помощью специаль- ного оператора замены (символа &). Этот прием часто используется для задания модифицируемых идентификаторов и кодов операций. К примеру, определим мак- рос, который предназначен для генерации в программе некоторой таблицы, при- чем параметры этой таблицы можно задавать с помощью аргументов макроко- манды:

После трансляции текста программы, содержащей эти строки, получатся сле- дующие макрорасширения: tаbl_b db 10 duр (0) tаbl_w dw 10 duр (0) Символ & можно применять и для распознавания формального аргумента в стро- ке, заключенной в двойные кавычки (""). Например, пum_сhаr macro message ;подсчитать количество (пum) символов в строке jmр ml еlеm db "Строка &message содержит" ;число символов в строке message в коде ASCII пum db 2 duр (0) db " символов", 10,13 , ' S ' ;конец строки ;дпя вывода функцией 09h ml: ;вывести elem на экран endm В связи с последним фрагментом разберем ситуацию, когда тело макроопреде- ления содержит метку или имя в директиве резервирования и инициализации дан- ных. Если некоторая макрокоманда вызывается в программе несколько раз, то при макрогенерации один и тот же идентификатор будет определен несколько раз, что, естественно, транслятор посчитает ошибкой. Для выхода из подобной ситуации применяют директиву LOCAL, которая имеет следующий синтаксис: local список_идентификаторов Эту директиву необходимо указывать непосредственно за заголовком макро- определения. Результатом работы директивы LOCAL будет генерация в каждом эк- земпляре макрорасширения уникальных имен для всех идентификаторов, пере- численных в операнде список_идентификаторов. Эти уникальные имена имеют вид ??хххх, где хххх — шестнадцатеричное число. Для первого идентификатора в пер- вом экземпляре макрорасширения хххх = 0000, для второго — хххх = 0001 и т. д. Кон- троль правильности размещения и использования этих уникальных имен берет на себя транслятор ассемблера. Для того чтобы окончательно разобраться в деталях, введем и оттранслируем листинг 14.2. В нем помимо некоторых ранее рассмотрен- ных макрокоманд содержится макрокоманда num_char. Ее назначение — подсчи- тывать количество символов в строке, адрес которой передается этой макрокоман- де в качестве фактического параметра. Строка должна удовлетворять требованию, предъявляемому к строке, предназначенной для вывода на экран функцией 09h прерывания 21h, то есть заканчиваться символом $. Другой момент, который нашел отражение в этой программе, — использование символа & для распознава- ния формального аргумента в строке, заключенной в кавычки 11" (см. последний фрагмент).

Листинг 14.2. Второй пример создания и использования макрокоманд

Листинг 14.2 (продолжение)

Макродирективы 305 В теле макроопределения можно размещать комментарии, и делать это особым образом. Если применить для обозначения комментария не один, как обычно, а два последовательных символа точки с запятой то при генерации макрорасшире- ния этот комментарий будет исключен. Если по какой-то причине необходимо присутствие комментария в макрорасширении, то его нужно задавать обычным образом, то есть с помощью одного символа точки с запятой, например: mes macro messsage ... ;этот комментарий будет включен в текст листинга ... ;;этот комментарий не будет включен в текст листинга епdm

<< | >>
Источник: В. И. Юров. Assembler. Учебник для вузов. 2-е изд. 2003

Еще по теме Макрокоманды:

  1. Л.О. Доліненко, В.О. Доліненко, С.О. Сарновська. Цивільне право України, 2006
  2. ЦИВІЛЬНЕ ПРАВО УКРАЇНИ
  3. ПЕРЕДМОВА
  4. Частина І ПРОГРАМА КУРСУ «ЦИВІЛЬНЕ ПРАВО УКРАЇНИ»
  5. Розділ І. Загальні положення цивільного права
  6. Тема 1. Поняття цивільного права. Предмет та метод, система цивільного права. Функції та принципи цивільного права
  7. Тема 2. Цивільне законодавство України
  8. Тема 3. Поняття, елементи та види цивільних правовідносин
  9. Тема 4. Здійснення цивільних прав і виконання обов’язків
  10. Тема 5. Захист цивільних прав та інтересів
  11. Тема 6. Об’єкти цивільних прав
  12. Тема 7.ФІЗИЧНІ особи як суб’єкти цивільного права
  13. Тема 8. Юридичні особи