- •Лекция 23
- •Схема трансляции программы с
- •Макросы
- •Макросы
- •Примеры макросов
- •Достоинства и недостатки макросов
- •Использование макросов
- •Использование макросов
- •Использование макросов
- •Использование макросов
- •Использование макросов
- •Пример использования
- •Макродирективы
- •Директивы WHILE и REPT
- •Пример использования WHILE и REPT
- •Директива IRP
- •Директива IRPC
- •Директивы условной
- •Директивы условной компиляции
- •Директивы условной компиляции
- •Директивы IF и IFE
- •Директивы IF и IFE
- •Директивы IFDEF и IFNDEF
- •Директивы IFDEF и IFNDEF
- •Директивы IFB и IFNB
- •Директивы IFB и IFNB
- •Директивы IFIDN, IFIDNI, IFDIF и IFDIFI
- •Директивы IFIDN, IFIDNI, IFDIF и IFDIFI
- •Директивы IFIDN, IFIDNI, IFDIF и IFDIFI
- •Вложенные
- •Директивы генерации ошибок
- •Безусловные директивы генерации ошибки
- •Условная генерация пользовательской ошибки
- •Условная генерация пользовательской ошибки
- •Условная генерация пользовательской ошибки
- •Пример с использованием константных выражений
Использование макросов
В некоторых случаях аргумент макроса является частью некоторого идентификатора. В таких случаях последовательность символов формального аргумента отделяют от остального контекста с помощью специального символа &.
Пример: |
|
|
|
|
def_array |
macro type=b, len:REQ |
|
||
arr_&type |
d&type len |
dup(0) |
|
|
endm |
|
|
|
|
.data |
|
|
|
|
def_array |
b,10 |
-> |
arr_b |
db 10 dup(0) |
def_array |
w, 5 |
-> |
arr_w |
dw 5 dup(0) |
|
|
|
|
|
Пример использования
;текст файла mymacro.inc |
;текст программы |
|
|||
init_ds macro |
.486 |
|
|
||
|
mov |
ax, @Data |
model small |
|
|
|
mov |
ds, ax |
include mymacro.inc |
|
|
endm |
|
purge cls_reg |
|
||
out_str |
macro str |
Data SEGMENT use16 |
|||
|
push |
ax |
ASSUME ds:Data |
||
|
mov |
ah, 09h |
mess |
db |
'Hello world!',0dh,0ah,'$' |
|
mov |
dx, offset str |
Data ENDS |
|
|
|
int |
21h |
Stck SEGMENT use16 stack |
||
|
pop |
ax |
ASSUME ss:Stck |
|
|
endm |
|
db |
256 dup(0) |
||
cls_reg |
macro rg |
Stck ENDS |
|
||
|
xor |
rg, rg |
Code SEGMENT use16 |
||
|
endm |
|
ASSUME cs:Code |
||
exit_m |
macro |
start: |
|
|
|
|
mov |
ax, 4c00h |
init_ds |
|
|
|
int |
21h |
out_str mess |
|
|
endm |
|
exit_m |
|
|
|
|
|
|
Code ENDS |
|
|
|
|
|
end start |
|
|
|
|
|
|
|
|
Макродирективы
Спомощью макросредств ассемблера можно не только частично изменять входящие в макроопределения строки, но и модифицировать сам набор этих строк и порядок их следования. Это можно сделать с помощью макродиректив (или просто директив).
Группы директив:
Директивы повторения WHILE, REPT, IRP и IRPC
Директивы управления процессом генерации макрорасширения EXITM и GOTO.
Директивы WHILE и REPT
Директивы WHILE и REPT применяют для повторения определенное количество раз некоторой последовательности строк.
WHILE константное_выражение последовательность_строк ENDM
REPT константное_выражение последовательность_строк ENDM
Отличие WHILE от REPT заключается в том, что последняя директива автоматически уменьшает счетчик.
Пример использования WHILE и REPT
def_sto_1 macro id_table, ln:=<5> |
def_sto_2 macro id_table, ln:=<5> |
||
Id_table label byte |
Id_table label byte |
||
len = ln |
|
rept len |
|
while len |
|
db |
0 |
db |
0 |
endm |
|
len = len – 1 |
endm |
|
|
endm |
|
|
|
endm |
|
|
|
Директива IRP
Синтаксис директивы:
IRP формальный_аргумент, <строка_сомволов_1, … , строка_символов_2> последовательность_строк
ENDM
Директива повторяет последовательность строк n раз, т. е. столько раз, сколько строк символов заключено в угловые скобки во втором операнде. Повторение последовательности строк сопровождается заменой в ней формального аргумента строкой символов из второго операнда.
Пример: |
|
|
|
||
irp |
ini, <1,2,3,4,5> |
-> |
db |
1 |
|
|
db |
ini |
|
db |
2 |
endm |
|
|
db |
3 |
|
|
|
|
|
db |
4 |
|
|
|
|
db |
5 |
|
|
|
|
|
|
Директива IRPC
Синтаксис директивы:
IRPC формальный_аргумент, строка_символов последовательность строк
ENDM
Действие этой директивы подобно IRP, но отличается тем, что она на каждой очередной итерации заменяет формальный аргумент очередным символом из строки символов.
Пример: |
|
|
|
|
||
irpc |
rg, <abcd> |
-> |
push |
ax |
||
|
push |
rg&x |
|
push |
bx |
|
endm |
|
|
|
push |
cx |
|
|
|
|
|
|
push |
dx |
|
|
|
|
|
|
|
Директивы условной
|
компиляции |
Два типа директив: |
|
|
директивы компиляции по условию позволяют проанализировать |
|
определенные условия в ходе генерации макрорасширения и при |
|
необходимости изменить этот процесс; |
|
директивы генерации ошибок по условию также контролируют ход |
|
генерации макрорасширения с целью генерации или обнаружения |
|
определенных ситуаций, которые могут интерпретироваться как |
|
ошибочные. |
С этими директивами применяются директивы управления процессом генерации макрорасширений EXITM и GOTO.
Директива EXITM не имеет операндов, и ее действие заключается в том, что она немедленно прекращает процесс генерации макрорасширения, начиная с того места, где она встречалась в макроопределении.
Директива GOTO имя_метки переводит процесс генерации макроопределения в другое место, прекращая тем самым последовательные разворачивание строк макроопределения. Метка, на которую передается управление, имеет специальный формат:
:имя_метки
Директивы условной компиляции
Директивы компиляции по условию:
директивы IF и IFE – условная трансляция по результату вычисления логического выражения;
директивы IFDEF и IFNDEF – условная трансляция по факту определения символического имени;
директивы IFB и IFNB – условная трансляция по факту определения фактического аргумента или вызове макрокоманды;
директивы IFIDN, IFIDNI, IFDIF и IFDIFI – условная трансляция по результату сравнения строк символов.
Директивы условной компиляции
Синтаксис директив компиляции по условию:
IFxxx логическое_выражение_или_аргументы фрагмент_програмы_1
ELSE фрагмент_програмы_2
ENDIF