- •1. Предварительные сведения 6
- •2. Процессоры intel в реальном режиме 11
- •3. Директивы и операторы ассемблера 51
- •Введение
- •1. Предварительные сведения
- •1.1. Подготовка программ на языке ассемблера
- •1.2. Представление данных в компьютерах
- •1.2.1. Двоичная система счисления
- •1.2.2. Биты, байты и слова
- •1.2.3. Шестнадцатеричная система счисления
- •1.2.4. Числа со знаком
- •1.2.5. Логические операции
- •1.2.6. Коды символов
- •2. Процессоры intel в реальном режиме
- •2.1. Регистры процессора
- •2.1.1. Регистры общего назначения
- •2.1.2. Модели памяти и сегментные регистры
- •2.1.3. Стек
- •2.1.4. Регистр флагов
- •2.2.4. Косвенная адресация
- •2.2.5. Адресация по базе со смещением
- •2.2.6. Косвенная адресация с масштабированием
- •2.2.7. Адресация по базе с индексированием
- •2.2.8. Адресация по базе с индексированием и масштабированием
- •2.3. Основные непривилегированные команды
- •2.3.1. Пересылка данных
- •2.3.2. Двоичная арифметика
- •2.3.3. Десятичная арифметика
- •2.3.4. Логические операции
- •2.3.5. Сдвиговые операции
- •2.3.6. Операции над битами и байтами
- •2.3.7. Команды передачи управления
- •2.3.8. Строковые операции
- •2.3.9. Управление флагами
- •2.3.10. Загрузка сегментных регистров
- •2.3.11. Другие команды
- •3. Директивы и операторы ассемблера
- •3.1. Структура программы
- •3.2. Директивы распределения памяти
- •3.2.1. Псевдокоманды определения переменных
- •3.2.2. Структуры
- •3.3. Организация программы
- •3.3.1. Сегменты
- •3.3.2. Модели памяти и упрощенные директивы определения сегментов
- •3.3.4. Процедуры
- •3.3.5. Конец программы
- •3.3.6. Директивы задания набора допустимых команд
- •3.3.7. Директивы управления программным счетчиком
- •3.3.8. Глобальные объявления
- •3.3.9. Условное ассемблирование
- •3.4. Выражения
- •3.5. Макроопределения
- •3.5.1. Блоки повторений
- •3.5.2. Макрооператоры
- •3.5.3. Другие директивы, используемые в макроопределениях
- •3.6. Другие директивы
- •3.6.1. Управление файлами
- •3.6.2. Управление листингом
- •3.6.3. Комментарии
- •Литература
3.5. Макроопределения
Одно из самых мощных языковых средств ассемблера — макроопределения. Макроопределение (или макрос) — это участок программы, которому присвоено имя и который ассемблируется всякий раз, когда ассемблер встречает это имя в тексте программы. Макрос начинается директивой MACRO и заканчивается ENDM.
Пусть, например, описано макроопределение hex2ascii, переводящее шестнадцатеричное число, находящееся в регистре AL, в ASCII-код соответствующей шестнадцатеричной цифры:
hex2ascii macro
cmp al, 10
sbb al, 96h
das
endm
Теперь в программе можно использовать слово hex2ascii, как если бы это было имя команды, и ассемблер заменит каждое такое слово на три команды, содержащиеся в макроопределении. Разумеется, можно оформить этот же участок кода в виде процедуры и вызывать его командой CALL — если процедура вызывается больше одного раза, этот вариант программы займет меньше места, но вариант с макроопределением будет выполняться быстрее, так как в нем не будет лишних команд CALL и RET. Но скорость выполнения — не главное преимущество макросов. В отличие от процедур макроопределения могут вызываться с параметрами, так что, в зависимости от ситуации, включаемый код будет немного различаться, например:
s_mov macro register1, register2
push register1
pop register2
endm
Теперь можно использовать S_MOV вместо команды MOV для того, чтобы скопировать значение из одного сегментного регистра в другой.
Следующее важное средство, использующееся в макроопределениях, — директивы условного ассемблирования. Например: напишем макрос, выполняющий умножение регистра АХ на число, причем, если множитель — степень двойки, умножение будет выполняться более быстрой командой сдвига влево.
fast_mul macro number
if number eq 2
shl ax, 1 ; умножение на 2
elseif number eq 4
shl ax, 2 ; умножение на 4
elseif number eq 8
shl ax, 3 ; умножение на 8
. . . ; аналогично вплоть до:
elseif number eq 32768
shl ax, 15 ; умножение на 215
else
mov dx, number ; умножение на число, не являющееся
mul dx ; степенью двойки
endif
endm
Можно усложнить этот макрос, используя особенности команды LEA и комбинируя LEA, сдвиги и сложения, но уже сейчас он чрезмерно громоздкий. Эту проблему решает третье средство, постоянно использующееся в макросах, — блоки повторений.
3.5.1. Блоки повторений
Простейший блок повторений REPT выполняет ассемблирование участка программы заданное число раз. Например, если требуется создать массив байт, проинициализированный значениями от 0 до 0FFh, это можно сделать, повторив псевдокоманду DB следующим образом.
hexnumber = 0
hextable label byte ; имя массива
rept 256 ; начало блока
db hexnumber ; эти две строки ассемблируются
hexnumber = hexnumber+1 ; 256 раз
endm
Блоки повторений, так же как макроопределения, могут вызываться с параметрами. Для этого используются директивы IRP и IRPC:
irp параметр, <значение1, значение2. . .>
. . .
endm
irpc параметр, строка
. . .
endm
Блок, описанный директивой IRP, будет вызываться столько раз, сколько значений указано в списке (в угловых скобках), и при каждом повторении будет определена метка с именем parameter, равная очередному значению из списка. Например, следующий блок повторений сохранит в стеке регистры АХ, ВХ, СХ и DX:
irp reg, <ax,bx,cx,dx>
push reg
endm
Директива IRPC описывает блок, который выполняется столько раз, сколько символов содержит указанная строка, и при каждом повторении будет определена метка с именем parameter, равная очередному символу из строки. Если строка содержит пробелы или другие символы, отличные от разрешенных для меток, она должна быть заключена в угловые скобки. Например, следующий блок задает строку в памяти, располагая после каждого символа строки атрибут 0Fh (белый символ на черном фоне), так что эту строку затем можно будет скопировать прямо в видеопамять.
irpc character,<строка символов>
db ‘&character&’, 0Fh
endm
В этом примере используются амперсанды для того, чтобы вместо параметра character было подставлено его значение даже внутри кавычек. Амперсанд — это один из макрооператоров — специальных операторов, которые действуют только внутри макроопределений и блоков повторений.