Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Roman legionnaire vs Knight Artorias
Ghost-Skeleton in DSR
Expedition SCP-432-4
Expedition SCP-432-3 DATA EXPUNGED

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Различные авторы Весь текст 2311.07 Kb

Программирование и кодирование

Предыдущая страница Следующая страница
1 ... 7 8 9 10 11 12 13  14 15 16 17 18 19 20 ... 198
            @ForEnd MACRO
                    IFNDEF          ?for_level
            ; ОШИБКА - "@ForEnd" без открытого оператора "FOR"
                    EXITM
                    ENDIF
                    IF  (?for_level LT 10)      page_end12
            ;
                    EXITM
                    ENDIF
            ;;
                    @DecSym          ?for_nest,%?for_level
            ;;
                    @MakeJmp         ?for_,%?for_level,?for_nest
            ;;
                    @IncSym          ?for_nest,%?for_level
            ;;
                    @MakeJmpLabel    ?for_,%?for_level,?for_nest
            ?for_level       =       ?for_level- 1
                    ENDM
            ;; **************************************************

                      Как работают структурированные макросы

            Сложность этих  макросов  вытекает  из необходимости поддержки
         вложенных структур управления.  Рассмотрим пример, приведенный на
         Рис.1-2.  Каждая  конструкция  IF-THEN-ELSE  требует наличия трех
         операторов перехода с тремя уникальными метками. Однако для запо-
         минания уникальных меток, сгенерированных директивой LOCAL, мы не
         можем использовать символы - нам приходится создавать собственные
         метки на базе счетчиков. Это обеспечивает прямое управление зада-
         чей.
            Для единичных  уровней вложенности достаточно простого счетчи-
         ка. Обратите внимание,  как на Рис. 1-2 конструкция IF-THEN-ELSE,
         связанная  с  условием  b,  использует  последовательность  меток
         3,4,5.  Это реализовать просто,  так как метки используются в том

                                      - 1-39 -
         же порядке, что и команды перехода, и метки перехода. Однако, как
         только появляются вложенные структуры управления, простой счетчик
         не справляется. Мимолетный взгляд на последовательность меток для
         всех трех операторов 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-40 -
            Для сравнения  эти уникальные составные метки, сгенерированные
         нашими структурированными макросами,  показаны в  Листинге  1-15.
         Первые две цифры числа являются уровнем вложенности, значение ко-
         торого начинается с 10 с тем, чтобы для уровня вложенности всегда
         были  зарезервированы  две  цифры.  Это  предотвращает совпадение
         уровня 1 счетчика 11 (1-11) с уровнем 11 счетчика 1 (11-1).
            Краткий текст программы в  точности  соответствует  тому,  что
         представлено на Рис.  1-2.  При детальном рассмотрении мы увидим,
         что расширенные макро на языке ассемблера создают те же  структу-
         ры, что представлены на Рис.1-2.
            Так как метки состоят из трех частей,  каждый тип макро струк-
         турного управления должен поддерживать набор счетчиков.  Этот на-
         бор включает в себя символ счетчика для указания  текущего уровня
         вложенности. Для обобщения задачи сопровождения этих счетчиков мы
         создали следующие макросы:  testsym,  zerosym,  incsym и  decsym.
         Этим  макросам  передаются аргументы,  которые они используют для
         создания счетчиков.  Аргументы представляют собой  идентификаторы
         типа (?if_) и текущие уровни вложенности.


                   Приемы кодирования и некоторые предупреждения

            Когда необходимо  создать  действительную  команду  перехода и
         метку перехода,  мы будем  использовать  макросы  mkjmp,  mkjmp2,
         mklbl  и  mklbl1.  Действительные метки состоят из идентификатора
         типа и номеров.  Единственный способ получить  числовое  значение
         символа заключается  в применении оператора процента (%), который
         действителен только при использовании с аргументом  вызова макро.
         Мы хотим вычислить символ, определяемый двумя элементами информа-
         ции из счетчика, так:

            mkjmp2      p1,p2,%&p3&p2

            Однако Руководство по MASM сообщает нам,  что оператор  ампер-
         санда  (&) не может быть использован в вызове макро.  Таким обра-
         зом, мы должны создать временную переменную и использовать ее.

            ??tmp =     &p3&p2
                    mkjmp2 p1,p2,%??tmp

            Все это  влечет за собой следующее.  Первая форма,  содержащая
         амперсанды в вызове макро,  должна работать. Однако выбор скрытой
         возможности вызывает проблемы будущей совместимости и даже реали-
         зуемости. Кроме того, Вы всегда должны задаваться вопросом, может
         ли неподдерживаемая   или несанкционированная функция зависеть от
         реализации совместимости.  Решение этой дилеммы остается за чита-
         телем.
            Авторы использовали  эту  несанкционированную  возможность   в
         программе,  не генерирующей программного кода, но решающей знаме-
         нитую задачу "Ханойские башни" в рекурсивной манере.  Кроме того,
         для  достижения общности наш метод создания символов счетчиков из
         нескольких частей позволяет  при  необходимости  создавать  новые
         счетчики.  Перед своим использованием эти счетчики должны инициа-
         лизироваться,  в противном случае первая  попытка  увеличить  или

                                      - 1-41 -
         уменьшить  их значение вызовет ошибку "Символ не определен".  Ис-
         пользуя условный оператор IFDEF,  можно проверить,  требуется  ли
         инициализация при каждом использовании символа.
            Инициализация связана  еще с одной тонкостью работы MASM.  Как
         мы установили, MASM является двухпроходным ассемблером, определя-
         ющим  символы при первом проходе и затем использующим их при вто-
         ром.  Это значит,  что определения символов защищены  от  первого
         прохода  ко  второму.  Таким образом,  когда MASM начинает второй
         проход,  все счетчики первого прохода уже определены  и  содержат
         свои старые значения. Если в начале второго прохода переинициали-
         зация символов не происходит,возникает фазовая  ошибка,  так  как
         начальные значения счетчиков отличаются.
            Для инициализации символов на первом проходе необходима  конс-
         трукция  IFDEF,  так  как заранее мы не знаем,  сколько счетчиков
         потребуется,  а использования IFDEF на втором проходе недостаточ-
         но.  Мы решили эту проблему, создав символы ?р2sw ..., которые на
         втором проходе анализируются на необходимость установки в нулевые
         значения.  Имя получается из Switch (переключателя) фазы 2.  Этот
         процесс проверки предоставляет хорошую возможность выявить,  при-
         надлежат  ли уровни вложенности самому верхнему уровню, указывая,
         что конструкции IF-IFEND, DOWHILE-DOEND и т.д. спарены правильно.
            В Листинге  1-16 приведены простые примеры расширения макросов
         структурного управления, определенных ранее. Как можно видеть, мы
         подавили  те  части  расширения,  которые не вырабатывают код или
         метки переходов.  Если Вы хотите ознакомиться с работой этих мак-
         росов  более  детально,  используйте директиву .LALL.  Прибегайте
         только к сокращенному примеру, так как обработка этих макро вызы-
         вает выполнение множества шагов.  Количество шагов также объясня-
         ет, почему происходит увеличение требуемого времени ассемблирова-
         ния   программы.   Используя  эти  макро,  не  ожидайте  быстрого
         ассемблирования, но рассчитывайте на быстрое кодирование.


                  Листинг 1-15. Вложенная структура IF-THEN-ELSE

         ----------------------------------------------------------------
                         ; Сжатый исходный код программы

                      @IfTrue e             условие (a)
                        @IfTrue e           условие  (b)
                        @IfElse             "else" для условия (b)
                        @IfEnd              конец условия (b)
                      @IfElse               "else" для условия (a)
                        @IfTrue e           условие (c)
                        @IfElse             "else" для условия (c)
                        @IfEnd              конец условия (c)
                      @IfEnd                конец условия (a)
                         ; Листинг расширения
                      @IfTrue e             условие (a)
Предыдущая страница Следующая страница
1 ... 7 8 9 10 11 12 13  14 15 16 17 18 19 20 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама