Одно из самых мощных языковых средств ассемблера — макроопределения. Макроопределением (или макросом) называется участок программы, которому присвоено имя и который ассемблируется всякий раз, когда ассемблер встречает это имя в тексте программы. Макрос начинается директивой MACRO и заканчивается ENDM. Например: пусть описано макроопределение hex2ascii, переводящее шестнадцатеричное число, находящееся в регистре AL, в ASCII-код соответствующей шестнадцатеричной цифры:
hex2ascii macro cmp al,10 sbb al,69h das endm
Теперь в программе можно использовать слово hex2ascii, как если бы это было имя команды, и ассемблер заменит каждое такое слово на три команды, содержащиеся в макроопределении. Разумеется, можно оформить этот же участок кода в виде процедуры и вызывать его командой CALL — если процедура вызывается больше одного раза, этот вариант программы займет меньше места, но вариант с макроопределением станет выполняться быстрее, так как в нем не будет лишних команд CALL и RET. Однако скорость выполнения — не главное преимущество макросов. В отличие от процедур макроопределения могут вызываться с параметрами, следовательно, в зависимости от ситуации, включаемый код будет немного различаться, например:
s_mov macro register1,register2 push register1 pop register2 endm
Теперь можно использовать S_MOV вместо команды MOV для того, чтобы скопировать значение из одного сегментного регистра в другой.
Следующее важное средство, использующееся в макроопределениях, — директивы условного ассемблирования. Например: напишем макрос, выполняющий умножение регистра AX на число, причем, если множитель — степень двойки, то умножение будет выполняться более быстрой командой сдвига влево.
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 ; Умножение на 32768 else mov dx,number ; Умножение на число, не являющееся mul dx ; степенью двойки. endif endm
Можно, конечно, усложнить этот макрос, применяя особые свойства команды LEA и ее комбинации, сдвиги и сложения, однако в нынешнем виде он чрезмерно громоздкий. Проблема решается с помощью третьего средства, постоянно использующегося в макросах, — блоков повторений.