Обработка макроопределений.
Сначала рассмотрим, что делает макрогенератор, когда он встречает макроопределение (МО). Пусть в тексте программы имеется такой фрагмент (слева - номера строк программы):
| ...
10 | M1 MACRO OP,W
11 | LOCAL L
12 | L: OP AX,W
13 | ENDM
14 | M MACRO X,Y,Z
15 | MOV AX,X
16 | M1 ADD,Y
17 | MOV Z,AX
18 | ENDM
19 | ...
Пусть НС=10, т.е. сейчас макрогенератор должен обработать 10-ю строку программы. В ней находится директива MACRO, директива макроязыка, поэтому макрогенератор должен ее обработать. Как макрогенератор узнает, что это директива макроязыка? А очень просто. В макрогенератор заранее встроена таблица, в которой перечислены названия всех директив макроязыка. Выделив в очередной строке мнемокод, макрогенератор просматривает эту таблицу, и если в ней есть такое имя, то значит, это директива макроязыка, иначе это обычное предложения ЯА.
Конкретно для директивы MACRO макрогенератор выполняет следующие действия. С этой директивы начинается новое МО. Макрогенератор заносит сведения о новом макросе в специальную таблицу, называемую таблицей макросов (ТМ). Вначале эта таблица пуста, а затем она пополняется по мере появления новых МО. Примерный вид ее такой:
имя макроса формал.параметры локал.имена начало тела
-----------------------------------------------------------
M1 OP, W L 11 -> 12
M X, Y, Z - 15
...
В 1-й колонке указывается имя макроса (у нас - M1), во 2-й - имена формальных параметров этого макроса (у нас - OP и W); эта информация извлекается из заголовка МО. В 3-й колонке указываются локальные имена, т.е. имена из директивы LOCAL, но пока макрогенератор ничего о них не знает (директиву LOCAL он еще не видит), поэтому пока оставляет эту колонку пустой. В 4-й колонке указывается номер строки программы, с которой начинается тело макроса, - это текущее значение НС
плюс 1 (у нас - 11). На этом макрогенератор заканчивает обработку 10-й строки и, увеличив НС на 1, переходит к следующей строке.
Теперь НС=11. Это директива LOCAL, которая сообщает о локальных именах макроса. Макрогенератор все перечисленные в ней имена заносит в 3-ю колонку соответствующей строки ТМ (у нас - заносит L). Кроме того, поскольку директива LOCAL не относится к телу макроса, то в этой же строчке корректируется число в 4?й колонке - оно увеличивается на 1 [зачеркнуть 11 и записать 12]. Если бы за директивой MACRO не было директивы LOCAL, то ТМ уже не менялась бы.
Далее. Поскольку сейчас макрогенератору нечего делать с МО, то он пропускает все последующие строки программы вплоть до строки с директивой ENDM, оканчивающей МО. Поэтому текущим значением НС
становится 13. На этом вся обработка МО завершается. Никакая информация о МО ассемблеру не сообщается (это не его дело).
Макрогенератор увеличивает НС на 1 и идет дальше.
Итак, НС=14. Снова директива MACRO, снова начинается МО. Действия макрогенератора аналогичны. Во-первых, в ТМ добавляется новая строка со следующей информацией [записать]: имя - М, формальные параметры - X, Y и Z, локальных переменных - нет, начало тела - 14+1=15. Поскольку далее нет директивы LOCAL, то макрогенератор пропускает все последующие строки вплоть до директивы ENDM, поэтому значением НС
становится 18. На этом обработка МО заканчивается. Макрогенератор увеличивает НС на 1 и идет дальше.