|
|
|
|
Как работают структурированные макросы
Сложность этих макросов вытекает из необходимости поддержки вложенных структур управления. Рассмотрим пример, приведенный на Рис.1-2. Каждая
конструкция IF-THEN-ELSE требует наличия трех операторов перехода с тремя уникальными метками. Однако для запоминания уникальных меток, сгенерированных
директивой LOCAL, мы не можем использовать символы - нам приходится создавать собственные метки на базе счетчиков. Это обеспечивает прямое управление
задачей.
Для единичных уровней вложенности достаточно простого счетчика. Обратите внимание, как на Рис. 1-2 конструкция IF-THEN-ELSE, связанная с условием
b, использует последовательность меток 3,4,5. Это реализовать просто, так как метки используются в том же порядке, что и команды перехода, и метки
перехода. Однако, как только появляются вложенные структуры управления, простой счетчик не справляется. Мимолетный взгляд на последовательность меток
для всех трех операторов IF-THEN-ELSE выявляет серьезный недостаток последовательности. Данная проблема решается использованием для каждого уровня
вложенности своего счетчика.
Уникальные метки создаются посредством включения в каждую из них трех элементов информации. Первым элементом является идентификатор типа
структуры, например, ?if_us, do_, ?rep_.Знак вопроса используется для уменьшения вероятности конфликта с создаваемыми пользователем символами или
метками. Второй элемент информации представляет собой уровень вложенности, который используется для различения между номером метки n на одном уровне
вложенности и номером метки n на основном уровне вложенности и номером метки n на другом уровне вложенности.Наконец, для обеспечения уникальности метки
каждого перехода конкретного уровня вложенности включается значение счетчика.
СТРУКТУРА УПРАВЛЕНИЯ НА АССЕМБЛЕРЕ
[ j(a) 1_1:
[ jmp 1_2:
IF(условие а) ----[ L_1: . (а)старт true-
[ . |
. |
[ j(b) 1_3: |
IF(условие b)---[ jmp 1_4: |
[ L_3: (b) кoд true|
. |
. |
. |
[ jmp 1_5: |
ELSE ----------[ L_4: . (b) код false|
[ . |
. |
ENDIF ----------- L_5: (a) конец true-
[ jmp 1_6:
ELSE ------------[ L_2: (a) старт false-
[ . |
. |
. |
[ j(c) 1_7: |
IF(условие с) --[ jmp 1_8: |
[ L_7: (c) код true |
. |
. |
. |
[ jmp 1_9: |
ELSE-----------[ L_8: (c) код false |
[ . |
. |
. |
ENDIF------------- L_9: (a) конец false-
ENDIF---------------- L_6:
Рис.1-2. Структура управления IF и соответствующая ей
интерпретация на языке ассемблера
|
Для сравнения эти уникальные составные метки, сгенерированные нашими структурированными макросами, показаны в Листинге 1-15. Первые две цифры
числа являются уровнем вложенности, значение которого начинается с 10 с тем, чтобы для уровня вложенности всегда были зарезервированы две цифры. Это
предотвращает совпадение уровня 1 счетчика 11 (1-11) с уровнем 11 счетчика 1 (11-1).
Краткий текст программы в точности соответствует тому, что представлено на Рис. 1-2. При детальном рассмотрении мы увидим, что расширенные
макро на языке ассемблера создают те же структуры, что представлены на Рис.1-2.
Так как метки состоят из трех частей, каждый тип макро структурного управления должен поддерживать набор счетчиков. Этот набор включает в себя
символ счетчика для указания текущего уровня вложенности. Для обобщения задачи сопровождения этих счетчиков мы создали следующие макросы: testsym,
zerosym, incsym и decsym. Этим макросам передаются аргументы, которые они используют для создания счетчиков. Аргументы представляют собой
идентификаторы типа (?if_) и текущие уровни вложенности.
|
|