lect_12.ppt
- Количество слайдов: 12
ЛЕКЦИЯ № 12 МАКРОКОМАНДЫ И МАКРОДИРЕКТИВЫ Макросредства языка ассемблера предназначены для решения следующих проблем: • плохое понимание исходного текста программы; • ограниченность набора команд; • повторяемость некоторых мало отличающихся участков программы; • необходимость включения в программу участков кода, уже использовавшихся в других программах. Основная идея использования макросредств – использование подстановок, которые замещают определенным образом организованную символьную последовательность другой символьной последовательностью. Для реализации механизма макроподстановок процесс трансляции разбивается на два этапа. На первом этапе работает макроассемблер или макрогенератор, который заменяет макросы последовательностью команд ассемблера. На втором этапе уже собственно ассемблер 1 генерирует объектный код.
Псевдооператоры equ и = Предназначены для присвоения некоторому выражению символического имени или идентификатора. В качестве выражения могут использоваться константы, имена меток, символические имена и строки в апострофах. Синтаксис: имя_идентификатора equ строка или числовое_выражение имя_идентификатора = числовое_выражение Псевдооператор equ удобно использовать для обозначения часто используемых в программе объетов более удобными именами. Пример: masm model small stack 256 massize equ akk equ maselem equ 10 ; размерность массива ax ; переименовать регистр mas[bx][si] ; адресовать элемент массива 2
. data mas. code db massize dup(0) mov akk, @data ds, akk mov al, maselem … ; фактически mov al, mas[bx], [si] … Псевдооператор = удобно использовать для определения простых не зависящих от адреса загрузки математических выражений. Главным условием является возможность для транслятора вычислить это выражение во время трансляции. Пример: adr 1 db adr 2 dw len = 43 5 dup(0) 0 3
len = len+1 len = adr 2 - adr 1 Начиная с версии 3. 00 компилятор TASM содержит директивы, значительно расширяющие возможности работы с текстовыми макросами. • Директива слияния строк: идентификатор catstr строка 1, строка 2 pre name privet equ catstr <Привет, > <Саша> pre, name • Директива выделения подстроки в строке: идентификатор substr строка, номер-позиции, размер privet equ <Привет, Саша> name substr privet, 7, 4 4
• Директива определения вхождения одной строки в другую: идентификатор intstr номер-нач. -позиции, строка 1, строка 2 privet num equ instr <Привет, Саша> 0, privet, “C” ; num=8 • Директива определения длины строки: идентификатор sizestr строка privet equ <Привет, Саша> len sizestr privet ; len=10 Макрокоманды С помощью макрокоманд в текст программы можновставлять последовательности строк (которые логически могут быть данными или командами) и даже более того – привязывать их к контексту места вставки Макрокоманда определяется при помощи макроопределения. Синтаксис макроопределения следующий 5
имя-макрокоманды macro список-формальных-аргументов тело макроопределения endm Есть три варианта расположения макроопределений. • В начале исходного текста программы до сегмента кода и данных программы, чтобы не ухудшать читаемость программы. Этот вариант следует применять, если определяемые макрокоманды актуальны только для данной программы. • В отдельном файле. Этот вариант следует использовать, если определяемые макрокоманды будут использоваться и некоторыми другими программами. • В макробиблиотеке. Если создаются универсальные макрокоманды, которые будут использоваться практически всеми программами, то их целесообразно записать в так называемую макробиблиотеку. Чтобы сделать макроопределения, определенные в отдельном файле или в библиотеке, доступными, необходимо в начале исходного текста этой программы записать директиву include имя-файла 6
При этом недостатком является то, что включенным в текущую программу окажется весь текст включаемого файла. Для исправления такой ситуации можно использовать директиву purge, в качестве операндов которой через запятую перечисляются имена макрокоманд, которые не должны включаться в текст программы. … include iomac. inc purge … outstr, exit Функционально макроопределения похожи на процедуры. Их можно так же, как и процедуры, описав однажды где-то, вызывать любое число раз определенным способом. Но на этом сходство заканчивается. Различия между процедурами и макрокомандами: • в отличии от процедуры, текст которой неизменен, макроопределение в процессе макрогенерации может меняться в соответствии с набором фактических параметров. При этом коррекции могут подвергаться как операнды команд, так и сами команды. 7
• при каждом вызове макрокоманды ее текст в виде макрорасширения вставляется в программу. При вызове процедуры микропроцессор осуществляет передачу управления на начало процедуры, находящейся в некоторой области памяти в одном экземпляре. Для того, чтобы использовать описанное макроопределение в нужном месте программы, оно должно быть активизировано с помощью макрокоманды следующим образом имя-макрокоманды список-фактических-аргументов Макроподстановка не заключается в простой замене макрокоманды текстом макроопределения. Обычно макрокоманда содержит список фактических аргументов, которыми корректируется макроопределение. Места в теле макроопределения, которые будут замещаться фактическими аргументами из макрокоманды, обозначаются с помощью так называемых формальных аргументов. Процесс замещения формальных аргументов фактическими называется макрогенерацией, а результат этого процесса – макрорасширением. 8
Пример: clear_r macro rg ; очистка регистра rg xor rg, rg endm … Каждый фактический аргумент представляет собой строку символов, для формирования которой применяются следующие правила: • строка может состоять: из последовательности символов без пробелов, точек, запятых, точек с запятой; из последовательности любых символов, заключенных в угловые скобки. В этой последовательности можно указывать как пробелы, так и точки, запятые, точки с запятыми; • для того, чтобы указать, что некоторый символ внутри строки, 9 представляющей фактический параметр, является собственно символом
а не чем-то иным, например, некоторым разделителем или ограничивающей скобкой, применяется специальный оператор «!» . Этот оператор ставится непосредственно перед описанным выше символом, и его действие эквивалентно заключению данного символа в угловые скобки. • если требуется вычисление в строке некоторого константного выражения, то в начале этого выражения нужно поставить знак %. % константное_выражение – выражение вычисляется и подставляется в текстовом виде в соответствии с текущей системой счисления. Полный синтаксис формального аргумента следующий: имя_формального_аргумента[=тип], где тип может принимать значения: • REQ, которое говорит о необходимости явного задания фактического аргумента при вызове макрокоманды; • <любая_строка> - если аргумент при вызове макрокоманды не задан, то в соответствующие места будет вставлено значение по умолчанию, соответствующее значению любая_строка. 10
Не всегда ассемблер может без дополнительного указания распознать в теле макроопределения формальный аргумент. В частности, в том случае, если он является частью идентификатора. В этом случае последовательность символов формального аргумента отделяется от остального текста символом &. … def_table macro type=, len=REQ tabl_&type d&type len dup(0) endm …. data def_tabl b, 10 def_tabl w, 5 11
Пример: num_char local macro message m 1 … ; подсчитать количество (num) символов в строке jmp m 1 elem db “Строка &message содержит” num db 2 dup (0) db “символов”б 10, 13, ’$’ ; конец строки для вывода на экран m 1: … ; вывести elem на экран endm 12


