Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2014- СП 3.0 ЛАБЫ ОБЯЗАТ.doc
Скачиваний:
99
Добавлен:
01.03.2016
Размер:
896 Кб
Скачать
      1. Параметризация макросов

Макросы могут иметь формальные строковые параметры, которые перечисляются в строке заголовка после слова MACRO через запятую. Например, приведенное выше макроопределение можно переделать в параметризованное так.

Считалка MACRO парам1, п2, па3, параметр4, п5

парам1, п2, па3, параметр4, п5

Всем ребятам надо спать.

ENDM

Тогда при макровызове можно задать фактические параметры, которые будут подставлены на место формальных при макрорасширении:

Считалка Мы , , устали, , танцевать

будет преобразована макрогенератором в макрорасширение:

Мы,, устали,, танцевать

Всем ребятам надо спать.

Обратите внимание, что здесь второй и четвертый фактический параметры заданы пустыми. Фактический параметр заменяет в теле макроопределения формальный по принципу «строка заменяет строку».

      1. Уникальность меток при макрорасширениях

В макросах могут встречаться метки. Вот, например, макрос, который устанавливает флаги процессора в соответствии со значением параметра, а затем, если флаг знака S != 1 (старший бит равен 0, это значит, что если число рассматривать как знаковое, то оно положительное), то следует «перепрыгивание» на метку (число положительное, делать ничего не надо), а иначе число преобразуется в такое же, но с противоположным знаком. Короче, это вычисление абсолютной величины параметра. Слов много, а в ассемблерных командах все делается проще некуда:

Absval MACRO param

test param, param

jns metka

neg param

metka:

EMDM

В этом макросе кроется принципиальная ошибка. Суть её в том, что сколько раз будет произведена макрорасширение Absval, столько раз в исходный текст будет подставлена метка metka: . Мы помним, что метки – это адресные константы, равные адресу (смещению) метки в секции кода. Если в программе окажутся одинаковые метки в разных местах программы, то компилятор не разберётся с этой проблемой: у адресной константы не может быть одновременно несколько разных значений. Результат очевиден – компиляция прерывается с ошибкой «Повторяющиеся метки».

Выход из этой ситуации прост. Пусть макрогенератор сам «выдумывает» уникальные имена меток при выполнении макрорасширений. Чтобы он это стал делать, надо объявить встречающиеся в теле макроса метки как «локальные». Это надо написать сразу после заголовка макроопределения:

Absval MACRO param

LOCAL metka

test param, param

jns metka

neg param

metka:

EMDM

Теперь макровызов Absval EDXбудет расширено в

test EDX, EDX

jns ??0000

neg EDX

??0000:

Второй макровызов, пусть это будет Absval AL,будет расширен в

test AL, AL

jns ??0001

neg AL

??0001:

Имена ??0000 и ??0001 – это и есть уникальные имена меток, которые сочинил сам макрогенератор. Компилятор образует их из буквенной строки «??» и лепит справа символьную 16-ричную запись номера метки в диапазоне от 0000 до FFFF. (Известно, что символ ? в ассемблере рассматривается как буква, поэтому искусственные имена ??0000, ??0001 и т.д. синтаксически совершенно корректны). Номер увеличивается на 1 при каждом новом макрорасширении. Поучается, что макрогенератор в одной программе способен создать 0FFFFh = 65536 искусственных меток. Такое возможное их количество перекрывает все мыслимые практические потребности.