АССЕМБЛЕР. Компоновщик. Загрузчик. Макрогенератор


Обработка макроопределений.


            Сначала рассмотрим, что делает макрогенератор, когда он встречает макроопределение (МО). Пусть в тексте программы имеется такой фрагмент (слева - номера строк программы):

            |     ...

         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 и идет дальше.


Содержание раздела