|
В качестве примера зарезервируем N слов дан-
ных в наборе чисел от 1 до N:
@FirstTry MACRO N ;;определить макро с параметром N
NUMB = 0 ;;инициализировать число
REPT N ;;повторить нижеследующее N раз
NUMB = NUMB+1 ;; увеличить индекс
DW NUMB ;;определить слово NUMB
ENDM ;;закончить команду REPT
ENDM ;;конец макро
Заметим, что для каждой директивы MACRO должно присутствовать
ENDM. Первой переменной, NUMB, значение присваивается оператором
=, а не EQU, что позволяет изменять ее значение в блоке REPT.
Директива REPT представляет собой циклическую структуру, типа
do...while языка высокого уровня. Она повторяет действия, заклю-
ченные между REPT и ENDM, N раз. В данном случае происходит уве-
личение NUMB на 1, а затем создается слово, содержащее это число.
(Имейте в виду, что Вы указываете MASM на создание констант, ко-
торые будут ассемблироваться. Вы не указываете компьютеру цикл,
подлежащий проходу во время выполнения программы)
Если макроописание FirstTry поместить в начало нашей програм-
мы, а затем использовать его в сегменте данных с N, равным 4, мы
получим:
@FirstTry 4
что соответствует тому, что MASM будет ассемблировать четыре сло-
ва чисел от 1 до 4.
Это слишком простой пример использования макро. Разрешите ус-
ложнить его, создав таблицу двоично-десятичных чисел, которая мо-
жет служить таблицей просмотра при преобразовании шестнадцатирич-
ных данных в код BCD.
@BCDtable MACRO N ;;определить макро с параметром N
NUMB = 0 ;;инициализировать числа
HIGHBYTE = 0
REPT N ;;повторить нижеследующее N раз
NUMB = NUMB+1 ;;увеличить индекс
IF (NUMB GT 9)
NUMB = 0
HIGHBYTE = HIGHBYTE + 10H
ENDIF
IF (HIGHBYTE GT 90H)
EXITM
ENDIF
BCDNUMB = (NUMB OR HIGHBYTE)
DW BCDNUMB ;;определить слово с именем NUMB
ENDM ;; конец команды REPT
ENDM ;; конец макро
- 1-46 -
Этот пример значительно сложнее, но он не представляет ничего
особенного для опытного программиста. Прежде чем провести пост-
рочный анализ этих директив (термин "директива" мы используем для
обозначения того, что является командой для MASM, а не для ЦП),
разрешите рассмотреть результат работы программы с N, установлен-
ным в 20:
38 @BCDtable 20
39 0004 0001 2 DW BCDNUMB ;
40 0006 0002 2 DW BCDNUMB ;
41 0008 0003 2 DW BCDNUMB ;
42 000A 0004 2 DW BCDNUMB ;
43 000C 0005 2 DW BCDNUMB ;
44 000E 0006 2 DW BCDNUMB ;
45 0010 0007 2 DW BCDNUMB ;
46 0012 0008 2 DW BCDNUMB ;
47 0014 0009 2 DW BCDNUMB ;
48 0016 0010 2 DW BCDNUMB ;
49 0018 0011 2 DW BCDNUMB ;
50 001A 0012 2 DW BCDNUMB ;
51 001C 0013 2 DW BCDNUMB ;
52 001E 0014 2 DW BCDNUMB ;
53 002O 0015 2 DW BCDNUMB ;
54 0022 0016 2 DW BCDNUMB ;
55 0024 0017 2 DW BCDNUMB ;
56 0026 0018 2 DW BCDNUMB ;
57 0028 0019 2 DW BCDNUMB ;
58 002A 0020 2 DW BCDNUMB ;
Первый столбец представляет собой номера строк ассемблерного
листинга, второй - смещение адреса относительно модуля, а третий
- то, что мы хотели - таблицу чисел BCD от 1 до 20.
Теперь построчно рассмотрим все макро. Прежде всего мы инициа-
лизируем две переменные. NUMB будет зациклена от 1 до 9, предс-
тавляя младший байт, в то время как HIGHBYTE будет представлять
байт более высокого порядка. Остальной частью макро управляет ди-
ректива REPT.
|