- •Лабораторная работа № 4
- •Цель работы
- •Краткие сведения из теории На что опирается программирование на ассемблере
- •Состав пакета масм
- •Последовательность создания исполняемого ехе-модуля на масм
- •Режимы компоновки
- •Макроопределение и макрорасширение
- •Параметризация макросов
- •Уникальность меток при макрорасширениях
- •Макроконстанты
- •Макропеременные и макровычисления
- •Увидеть работу макрогенератора
- •Расширенный листинг
- •3. Порядок выполнения работы:
- •3.1 Создание консольной программы
- •3.2 Создание программы с графическим интерфейсом
- •3.3 Использование шаблона простой программы
- •3.5 Макроопределение и макрорасширение
- •3.6 Повторение строк repeat
- •3.7 Цикл for
- •3.8 Анализ расширенного листинга программы
- •4. Содержание отчёта
- •5. Вопросы к защите
- •Самостоятельная работа по лабораторной работе № 4 «Технология создания ассемблерных программ»
- •1. Установка масм32
- •2. Настройка переменной path
- •7. Превращение участка кода в макрос
- •8. Просмотр работы макрогенератора
- •9. Параметризация макроса
- •10. Локализация внутренних меток в макросах
- •11. Макроимена и макропеременные
- •12. Превратить исходный текст в макрос
- •13. Ручное макрорасширение
- •14. Наблюдение результата работы макрогенератора
Уникальность меток при макрорасширениях
В макросах могут встречаться метки. Вот, например, макрос, который устанавливает флаги процессора в соответствии со значением параметра, а затем, если флаг знака 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 искусственных меток. Такое возможное их количество перекрывает все мыслимые практические потребности.
Макроконстанты
Макроконстанта определяется с помощью ключевого слова EQU (от слова equivalence – равносильно). Например
One equ 2*3
Username equ 1024/8
Понимать это нужно так: макрогенератор строку «One» везде заменит на результат вычисления выражения 2*3, а строку «Username» - на результат вычисления выражения 1024/8. Единожды определив такие числовые макроконстанты, переопределить их потом нельзя. Замены имён макроконстант на строки-значения производятся в исходном тексте в строках, расположенных ниже определения. Поэтому макроконстанты нужно определять в самом начале asm-файлов.
Макропеременные и макровычисления
Макропеременные могут быть только целочисленными. Они создаются на период компиляции с помощью операции = (знак равенства). Значение константы в процессе компиляции можно переопределять сколько угодно раз. Например
MyVar = 10
Это переменные, с которыми работает компилятор ML как любое приложение работает со своими переменными. Компилятор может в процессе трансляции выполнять много вычислительных операций. В том числе можно программировать циклы, проверки условий. Рассмотрим некоторые примеры.
Создание в секции данных описания числового массива из десяти квадратов первых десяти целых чисел.
.data
A=1
Massiv Label Word
Repeat 10
Dw A*A
A = A+1
Endm
Макрогенератор создаст следующее:
.data
A=1
Massiv Label Word
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Dw A*A
A = A+1
Все вычисления выполнятся в период трансляции. Здесь же мы наблюдаем работу только макрогенератора, а он, как говорилось выше, манипулирует только текстами.
Пример – записать через цикл операторы сохранения в стек регистров, чьи имена заканчиваются на X:
irpc rg, ABCD
push rg&X
endm
