Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_MET_1.DOC
Скачиваний:
2
Добавлен:
25.08.2019
Размер:
595.97 Кб
Скачать

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 было подставлено его значение даже внутри кавычек. Амперсанд это один из макрооператоров — специальных операторов, которые действуют только внутри макроопределений и блоков повторений.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]