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

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


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)

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


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

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

Предыдущая страница Следующая страница
1 ... 3 4 5 6 7 8 9  10 11 12 13 14 15 16 ... 198
            Непосредственный     20    локально      0   неверно
            Регистровый          20    локально      0   неверно
            Метка данных         22    локально      Х   количество
                                                         байтов
            "Близкая" метка      21    локально     FFFF "близкая"
                                                         метка
            "Далекая" метка      21    локально     FFFE "далекая"
                                                         метка
            Код операции MASM    00    неверно       0   неверно
            Нонсенс              00    неверно       0   неверно
         -------------------------------------------------------------


            Список примеров можно продолжить. Хотя .TYPE и распознает име-
         на различных регистров,  он не распознает регистровые конструкции
         типа [BX] или ARRAY[BX][SI]. Односимвольная константа типа A рас-
         познается оператором .TYPE как переменная, определенная локально.
            Во время  первого  прохода  ассемблера  ссылка вперед никак не
         распознается.  IFDEF в качестве результата возвращает "не опреде-
         ленно",  .TYPE  возвращает  "неверно",  а TYPE возвращает нулевую
         длину. К ссылкам вперед может быть применено только одно правило:
         если возможно, не применять их вообще.

                    Фазовые ошибки и некоторые особенности MASM

            С использованием  операторов  MASM связана одна важная особен-
         ность.  MASM является двухпроходным ассемблером, назначающим зна-
         чения  символам на первом проходе и затем вычисляющим символы при
         втором проходе.  Программные метки и метки данных являются симво-
         лами.  Их значения определяются во время первого прохода, а затем
         используются на втором проходе для генерации программного кода.
            Рассмотрим следующее дерево событий.  При  обнаружении  ссылки
         вперед  MASM  не распознает метку на первом проходе и не способен
         определить ее тип. Попытка ссылки на этот символ вызывает появле-
         ние сообщения об ошибке "Символ не определен".  MASM обнаруживает
         эту ошибку на первом проходе,  но подавляет ее и  продолжает  ас-
         семблирование.  MASM  способен  подавить ошибку,  предположив тип
         символа из контекста, в котором он появился. Если это предположе-
         ние  неверно,  MASM может закончить свою работу,  выдав сообщение
         "фазовая ошибка между проходами",  или может укоротить команду  и
         поместить после нее команду nop (нет операции),  как заполнитель.
            Существует два способа устранения фазовых ошибок при  нормаль-
         ной  работе MASM.  В большинстве случаев MASM способен определить
         тип операндов из контекста. Программисты редко применяют переходы
         в  сегменте данных и обычно не добавляют программных адресов. Для
         тех специальных случаев,  когда MASM делает ошибочные предположе-
         ния,  программист может определить порядок работы ассемблера, ис-
         пользуя оператор перекрытия PTR (указатель).  С помощью оператора

                                     - 1-24  -
         PTR программист может явно указать тип ссылки вперед, и, следова-
         тельно, MASM не сделает ошибочного предположения. Однако, пытаясь
         выработать многоцелевые команды макро, мы значительно увеличиваем
         вероятность ошибочного выражения.  Если наши многоцелевые команды
         предназначены для обработки любых классов операндов,  точное зна-
         чение  такого класса трудно определить из контекста.  Кроме того,
         хотя использование PTR и может помочь в некоторых подобных случа-
         ях  (как мы увидим в макро @PushOP),  оно не достигает цели осво-
         бождения программиста от излишних деталей.
            Проанализировав то,  как ошибочное предположение  вырабатывает
         фазовую ошибку,  мы с большей вероятностью можем устранить ее по-
         явление.  Так как фазовые ошибки являются результатом смены неко-
         торыми символами (например,  меток) своих значений между прохода-
         ми,  важно,  чтобы макросы  вырабатывали  один  и  тот  же  объем
         программного  кода  на каждом проходе.  Это предохраняет значения
         меток, размещенных после макро, и объясняет, почему MASM забивает
         укороченные команды инструкциями NOP. От одного прохода к другому
         должны также оставаться постоянными программные метки.

                              Сравнение строк. Пример

            К сожалению,  способность оператора .TYPE распознавать  непос-
         редственные операнды и регистры значительно уменьшается при выяс-
         нении типа операндов макро. Так как особенно важно знать, являет-
         ся ли аргумент макро регистром,  мы должны сконструировать способ
         выявления этого.  Определение того,  является ли аргумент регист-
         ром,  обычно полезно только вместе с неявным предположением,  что
         если он не является регистром и не является определенной адресной
         ссылкой, то предположительно является ссылкой на непосредственные
         данные.
            Это хорошо сочетается с использованием условного ассемблирова-
         ния  на базе директив IRP и IRPC.  Целью в данном случае является
         определение принадлежности аргумента макро к  какому-либо набору.
         Для решения задачи - является ли аргумент регистром, используется
         сопоставление строк.  Так как  оператор  .TYPE  может  определить
         только то,  что эти регистры объявлены локально и абсолютны,  для
         явной проверки имени  регистра  применяется  макро  сопоставления
         строк. Эту  функцию  выполняет  приведенное  в Листинге 1-8 макро
         ?reg.


              Листинг 1-8. Макро сопоставления имен регистров - ?reg
         -----------------------------------------------------------------

            FALSE    EQU     0
            TRUE     EQU     0FFFFh
            ;;
            ;;**** ?REG - Определить, является ли аргумент регистром
            ;;
            ?reg     MACRO   arg
            ?isr8    =       FALSE
            ?isr16   =       FALSE
                     IRP     reg,
                     IFIDN   <&®>,<&arg>
                     ?isr16  =       TRUE
                     EXITM

                                      - 1-25 -
                     ENDIF
                     ENDM    ;; конец секции IRP
            ;; Если сравнились, остановиться здесь
                     IF      (?isr16)
                     EXITM
                     ENDIF
            ;; Если еще не сравнились, продолжить далее
                     IRP     reg,
                     IFIDN   <&®>,<&arg>
                     ?isr8   =        TRUE
                     EXITM
                     ENDIF
                     ENDM    ;; конец секции  IRP
            ;; Если сравнились, остановиться здесь
                     IF      (?isr8)
                     EXITM
                     ENDIF
            ;; Если не сравнились, попробовать прописные имена регистров
                     IRP     reg,
                     IFIDN   <&®>,<&arg>
                     ?sir16  =       TRUE
                     EXITM
                     ENDIF
                     ENDM    ;; конец секции IRP
            ;; Если сравнились, остановиться здесь
                     IF      (?isr16)
                     EXITM
                     ENDIF
            ;; Если еще не сравнились, попробовать еще
                     IRP     reg,
                     IFIDN   <&®>,<&arg>
                     ?isr8   =        TRUE
                     EXITM
                     ENDIF
                     ENDM    ;; конец секции IRP
                     ENDM    ;; конец макроописания
         -----------------------------------------------------------------

            Cердцевиной этого макро, как и любого макро сопоставления, яв-
         ляются команды:

            IRP       reg,
            IFIDN     <&®>,<&arg1>
            ?isr16    %        TRUE

            Интерпретировать эти строки можно так:

            Для reg равного ax...ss выполнить . . .
                Если reg равно аргументу arg . . .
                     Аргумент есть регистр!

            Здесь следует  остановиться  на  двух   интересных   моментах.
         Во-первых,  необходимо явно проверять имена регистров, написанные
         как малыми, так и большими буквами. Директива условного ассембли-
         рования  IFIDN сравнивает строки на точное соответствие. Несмотря
         на все усилия, макро ?reg не полно. Оно не сопоставляет имена ре-
         гистров, состоящие из одной большой и одной малой буквы (например

                                      - 1-26 -
         "aL"). Во-вторых,  необходимо  проводить  две  проверки: одну для
         16-битовых регистров и одну для 8-битовых регистров. В данной ре-
         ализации наличие двух отдельных проверок не приносит  нам никакой
         выгоды, однако такие проверки окажутся полезными в следующем при-
         мере.
            Макро ?reg  имеет  два дополнительных синтаксических элемента.
         Один - директива завершения макро EXITM.  Эта директива использу-
         ется для завершения работы макро ?reg при обнаружении совпадения.
            Менее очевидно использование двойного амперсанда  в  операторе
         IFIDN. Согласно Руководству по MASM фирмы Майкрософт пользователь
         должен "указывать столько амперсандов,  сколько  имеется  уровней
         вложенности".  Столь лаконичное выражение не вносит ясности в ре-
         шение проблемы.  "Уровни вложенности" относятся не к глубине бло-
         ков,  где появляется ссылка, а к глубине блоков, где находится ее
         описание. Таким образом, arg1 приводится только с одним амперсан-
         дом, в то время как reg, описание которого находится во вложенном
         блоке,  требует наличия двух амперсандов. Фирма Майкрософт не ут-
         верждает,  что это предел разрешенного количества уровней вложен-
         ности или количества требуемых амперсандов.  В тех случаях, когда
         казалось  бы необходимо указывать множество амперсандов,  попытки
         написания примеров, позволяющих выявить правильное функционирова-
         ние, не увенчались успехом.
            Приведенный Листинг 1-9 с макро ?reg показывает, что это макро
         выполняет  возложенную на него функцию.  Заметьте,что регистр bР,
         который распознается MASM,  отбрасывается макро ?reg.  Это  может
         быть  истолковано,  как необходимость соблюдения строгого правила
         ввода исходного текста программы с клавиатуры.


              Листинг 1-9. Тест макро сравнения имен регистров - ?reg
         -----------------------------------------------------------------

                       ?reg   ax      ; "AX" - регистр ?
            FFFF       dw     ?isr16               <--- TRUE
                       ?reg   CS      ; "CS" - регистр ?
            FFFF       dw     ?isr16               <--- TRUE
                       ?reg   zork    ; "ZORK" - регистр ?
            0000       dw     ?isr16               <--- FALSE
            0000       dw     ?isr8                <--- FALSE
                       ?reg   01234h  ; "1234" - регистр ?
            0000       dw     ?isr16               <--- FALSE
            0000       dw     ?isr8                <--- FALSE
                       ?reg   bР      ; "BP" - регистр ?
            0000       dw     ?isr16               <--- FALSE
Предыдущая страница Следующая страница
1 ... 3 4 5 6 7 8 9  10 11 12 13 14 15 16 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама