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

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


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

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


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

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

Предыдущая страница Следующая страница
1 ... 11 12 13 14 15 16 17  18 19 20 21 22 23 24 ... 198
                    je      bye   ;;если символа нет, продолжить
                    ENDIF       ;;конец проверки условия
                    IFIDN ,   ;;если EKOFLAG = EKO,

                                      - 1-54 -
                                ;;ассемблировать следующую строку
                    mov     ah,06h  ;;функция DOS по записи в
                                    ;;стандартный вывод
                    ELSE            ;;в противном случае
                      IFIDN ,  ;;если EKOFLAG=NOEKO,
                                          ;;ассемблировать
                      mov   ah,40h    ;;функция DOS по записи в файл
                      ELSE       ;;если аргумент не соответствует
                        .ERR     ;;выдать ошибку ассемблирования
                    %OUT Ошибка в макро @WritToFil - EKOFLAG не найден
                  ENDIF             ;;конец проверки условия
                ENDIF               ;;конец проверки условия
                int       21h       ;;вызов DOS
            bye:
                .CREF     ;;восстановить выдачу перекрестных ссылок
                ЕNDМ                ;;конец макро


            Теперь во время ассемблирования для определения  режима  DEBUG
         мы можем использовать опцию /d:
            MASM  myprgm,,,; /dDEBUG
         и все  вызовы макро WritToFil будут генерировать программный код,
         проверяющий ввод.
            Для определения,  ждем ли мы появление символа,  мы используем
         флаг (с оператором =,  а не equ,  Так как мы переопределяем его в
         следующих двух операторах IF).  Вместо (x eq 1 ) или (x eq 2)  мы
         могли  бы  закодировать x gt 0 или x NE 0,  тaк как действительно
         любое значение,  отличное от задаваемого при  инициализации  (0).
         Заметим,  что мы также добавили несколько новых директив. Символы
         ;; сообщают MASM, что комментарии не должны появляться в листинге
         ассемблера. Директива .ХСREF экономит время ассемблирования и па-
         мять для листинга перекрестных ссылок, сообщая MASM, что не нужно
         загромождать этот листинг именами,  используемыми только в макро.
         Директива .СREF восстанавливает выдачу  перекрестных  ссылок  для
         оставшейся части листинга.  Кроме того,  ее можно и не указывать.
         Мы также добавили директиву %OUT, которая будет выводить на экран
         вставленное в нее сообщение об ошибке.  Теперь мы поэксперименти-
         руем с некоторыми дополнительными возможностями.

                          Макро, вызывающее подпрограммы

            Одно из наиболее мощных применений макро заключается в универ-
         сальном  вызове подпрограмм аналогично вызовам подпрограмм в язы-
         ках высокого уровня.  Задача заключается в проталкивании несколь-
         ких параметров в стек и вызове подпрограммы.  Довольно просто, за
         исключением потребности макро приспособиться к  переменному числу
         параметров, которые в свою очередь могут иметь переменные размеры
         (байт,слово, двойное слово, четвертное слово и 10-байтовые значе-
         ния  с  плавающей точкой).  Для выполнения этих требований мы ис-
         пользуем операторы .TYPE и TYPE (обратите внимание на точку перед
         первым оператором). Использование оператора .TYPE позволяет макро
         поддерживать как регистр типа BX,  так и слово или  байт  данных.
         Конструкция .TYPE х возвращает байт,  набор битов которого содер-
         жит следующую информацию:


                                      - 1-55 -
            БИТ 0 = 1, если х программно зависимо, иначе = 0
            БИТ 1 = 1, если х зависимо от данных, иначе  = 0
            БИТ 5 = 1, если х определено, иначе          = 0
            БИТ 7 = 1, если х - внешний параметр, если локальный
                                    или общий            = 0
         Все остальные биты нулевые.
            Например, если  х  зависимо от данных,  определено и локально,
         оператор.TYPE х возвращает значение 001000100b (или 22h);  -- ус-
         тановлены  биты  1 и 5.  Так как мы хотим разрешить использование
         регистров (программно зависимых) в качестве параметров,  мы будем
         применять оператор .TYPE для сообщения о наличии параметров,  за-
         висящих от данных. Так как мы хотим поддерживать данные различной
         длины отдельно,  мы используем оператор TYPE,  возвращающий длину
         их аргументов в байтах. Например,

            TYPE N =  1, если N  - байт
            TYPE N =  2, ecли N  - слово
            TYPE N =  4, ecли N  - двойное слово
            TYPE N =  8, если N  - четверное слово
            TYPE N = 10, если N  - десятибайтовое слово (т.е. с плаваю-
                                   щей  точкой)
            TYPE N = XX, если N  - cтруктура длиной в хх байтов
            TYPE N = FFFF,если N - "близкая" программная метка
            TYPE N = FFFE,если N - "удаленная" программная метка

            Следующее макро иллюстрирует использование директив TYPE и
            .TYPE:

            @FcnCall MACRO  Fnctn,ParmList  ;;список подпро-мм и парам-ов
                   IRP     N,    ;;неопределен. повторение
                   BYTELENGTH = TYPE N      ;;получить длину "проталкива-
                              ;;емых" элементов в байтах
                     IF ((.TYPE N ) NE  22H)     ;;N определено и зави-
                                                 ;;симо от данных?
                     push  N ;;если нет - предположить 16-битовый регистр        ;;
                     ELSE    ;;в противном случае предположить данные
                       IF (BYTELENGTH EQ 2) ;;тогда, если параметр 2-
                                            ;;байтовый,
                     push N      ;;протолкнуть
                     ELSE        ;;в противном случае
                       IF (BYTELENGTH EQ 1)  ;;если параметр 1-байтовый,
                                  ;;предположить, что AX доступен
                       mov      ah,0  ;;очистить верхнюю часть AX
                       mov      al,N  ;;сделать  параметр словом
                       push     ax  ;;так, чтобы мы могли продвинуть его
                       ELSE         ;;в противном случае
                         IF (BYTELENGTH EQ 4) ;;если параметр 4-байтовый
                         push    word ptr N     ;;продвинуть 1-ое и
                         push    word ptr N + 2  ;;2-ое слово
                         ELSE      ;;в противном случае
                           IF (BYTELENGTH EQ 8) ;;если параметр 8-байт.
                           push  word ptr N     ;;продвинуть 1-ое,
                           push  word ptr N + 2   ;;  2-ое
                           push  word ptr N + 4   ;;  3-ье и
                           push  word ptr N + 6   ;;  4-ое слово
                           ELSE         ;;в противном случае
                             IF  (BYTELENGTH EQ  10)   ;;если параметр
                                             ;;10-байтовый, продвинуть

                                      - 1-56 -
                             push word ptr N   ;; 1-ое
                             push word ptr N + 2       ;; 2-ое
                             push word ptr N + 4       ;; 3-ье
                             push word ptr N + 6       ;; 4-ое  и
                             push word ptr N + 8       ;; 5-ое слово
                             ELSE
                             .ERR
                             ENDIF
                           ENDIF
                         ENDIF
                       ENDIF
                     ENDIF
                   ENDIF
                 call Fnctn
                 ENDM                               ;;конец IRP
                 ENDM                               ;;конец макро


            Замечательным преимуществом данного макро является то,  что мы
         заранее не указываем количество параметров,  которое хотим перес-
         лать подпрограмме, до непосредственного обращения к ней. Мы можем
         вызвать одну подпрограмму с тремя параметрами,  а другую - с дву-
         мя. Например:

            @FcnCall Fcn1,
            @FcnCall Fcn2,

            Для любого вызова подпрограммы мы можем иметь фактически неог-
         раниченное число параметров.
            В данном макро имеется много недостатков. Одним из этих недос-
         татков является то,  что мы не  покрыли  все  возможные  значения
         BYTELENGTH,  типа программных меток и структур;  мы предположили,
         что регистр AX доступен только для однобайтового параметра и т.д.
         Для большинства этих недостатков существует дилемма: цикл, на ба-
         зе BYTELENGTH, мог бы поддерживать все возможные длины данных, но
         при  этом  могли  возникнуть другие проблемы,  поэтому мы даже не
         рассматриваем альтернативы, а считаем своей задачей лишь "протал-
         кивание" данных в вызываемую подпрограмму!  Пример служит для ил-
         люстрации директив TYPE и .TYPE,  однако рассмотрение общецелевой
         функции  вызова  подпрограмм  требует нечто большего.  Прежде чем
         продолжить разбор этого макро мы сделаем короткое  отвлечение  на
         введение понятия структуры.

                            Применение директивы STRUC

            Структуры представляют собой директивы ассемблера, позволяющие
         нам строить сложные форматы данных,  состоящие из байтов,  слов и
         т.д.,  таким  образом,  чтобы они имели большую смысловую вырази-
         тельность и доступность. Они очень похожи на структуры Си и запи-
         си Паскаля.  А отличаются они тем, что в МASM индексирование зат-
         руднено,  вложенность  вообще  запрещена.  В  качестве   примера,
         который  мы  можем использовать в макросе,  передающем параметры,
         разрешите предположить,  что Вы написали  программу,  выполняющую
         математические  функции.  Ниже  приводится структура,  которую Вы
         могли бы создать:


                                      - 1-57 -
            MathNumbers      STRUC
            BooLean1         DB         (0)     ; 1 байт
            BooLean2         DB         (0)     ; 1 байт
            ShortInteger1    DW         (0)     ; 1 слово
            ShortInteger2    DW         (0)     ; 1 слово
            LongInteger1     DD         (0)     ; 1 двойное слово
            LongInteger2     DD         (0)     ; 1 двойное слово
            Float1           DT         (0)     ; 1 10-байтовое слово
                                                ; (для 8087)
            Float2           DT         (0)     ; 1 10-байтовое слово
                                                ; (для 8087)
            MathNumbers      ENDS

            MathNumbers определяет тип структуры. STRUС и ENDS ограничива-
         ют начало и конец описания структуры.  Теперь мы можем  использо-
         вать MаthNumbers для объявления некоторых данных,  например, так:

            TrueFalse   MathNumbers    <1,0,,,,,,>
            MaxMinShort MathNumbers    <,,32767,-32768,,,,>
            MaxMinLong  MathNumbers    <,,,,2147483647,-2147483648,,>
            e           MathNumbers    <,,,,,,,2.718281828>

            ListLength  = 100
            MathList    MathNumbers    ListLength dup <,,,,,,,>

            Память зарезервирована под 104 числа.  При 34 байтах под число
         наш список чисел займет 3536 байтов.  Первоначально  структура  в
         своем описании инициализируется в 0,  а затем в секции данных ус-
         танавливается в различные значения.  Структуры  могут  рассматри-
         ваться  как директивы данных,  определяемые пользователем.  Имена
         элементов структуры преобразуются MASM в побайтовое смещение  от-
Предыдущая страница Следующая страница
1 ... 11 12 13 14 15 16 17  18 19 20 21 22 23 24 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама