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

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


    Прохождения игр    
SCP-127: Живое оружие
StarCraft II: Wings of Liberty |#17| Media Blitz
StarCraft II: Wings of Liberty |#16| Supernova
DARK SOULS™: REMASTERED |#14| Gravelord Nito

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


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

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

Предыдущая страница Следующая страница
1 ... 9 10 11 12 13 14 15  16 17 18 19 20 21 22 ... 198
            39 0004  0001        2 DW   BCDNUMB  ;
            40 0006  0002        2 DW   BCDNUMB  ;
            41 0008  0003        2 DW   BCDNUMB  ;
            42 000A  0004        2 DW   BCDNUMB  ;
            43 000C  0005        2 DW   BCDNUMB  ;
            44 000E  0006        2 DW   BCDNUMB  ;
            45 0010  0007        2 DW   BCDNUMB  ;
            46 0012  0008        2 DW   BCDNUMB  ;
            47 0014  0009        2 DW   BCDNUMB  ;
            48 0016  0010        2 DW   BCDNUMB  ;
            49 0018  0011        2 DW   BCDNUMB  ;
            50 001A  0012        2 DW   BCDNUMB  ;
            51 001C  0013        2 DW   BCDNUMB  ;
            52 001E  0014        2 DW   BCDNUMB  ;
            53 002O  0015        2 DW   BCDNUMB  ;
            54 0022  0016        2 DW   BCDNUMB  ;
            55 0024  0017        2 DW   BCDNUMB  ;
            56 0026  0018        2 DW   BCDNUMB  ;
            57 0028  0019        2 DW   BCDNUMB  ;
            58 002A  0020        2 DW   BCDNUMB  ;

            Первый столбец представляет собой номера  строк  ассемблерного
         листинга,  второй - смещение адреса относительно модуля, а третий
         - то, что мы хотели - таблицу чисел BCD от 1 до 20.
            Теперь построчно рассмотрим все макро. Прежде всего мы инициа-
         лизируем две переменные.  NUMB будет зациклена от 1 до 9,  предс-
         тавляя  младший байт,  в то время как HIGHBYTE будет представлять
         байт более высокого порядка. Остальной частью макро управляет ди-
         ректива REPT. Первым делом внутри блока повторения мы увеличиваем
         на 1 переменную NUMB.  Затем определяем, равна ли она 10, и, если
         это так, для очередного запуска цикла устанавливаем ее в 0. Затем
         добавляем к HIGHBYTE - 10, увеличивая цифру десятков числа в фор-
         мате BCD. Далее завершаем оператор IF.
            Следующим шагом проверяем,  если построенное нами число в  BCD
         больше  того,  что может храниться в слове,  то выходим из макро.
         Предпоследним действием создаем число в  BCD,  выполняя  операцию
         логического  "ИЛИ" над цифрой единиц и цифрой десятков.  Наконец,
         создаем слово,  содержащее требуемое число в BCD. Первый ENDM за-
         вершает цикл REPT;  второй - завершает макро. Для ссылки к списку
         чисел BCD необходима метка.  Мы не хотим  набирать  метку  каждый
         раз, когда обращаемся к макро. Мы используем оператор подстановки
         @, чтобы эту метку создавал MASM:

            @BCDtable MACRO N    ;;определить макро с параметром N
                    BCD1to&N label word       ;;определить метку
                    NUMB = 0     ;;инициализировать числа
                    HIGHBYTE = 0
                      REPT N     ;;повторить нижеследующее N раз

                                      - 1-47 -
                      NUMB = NUMB+1   ;;увеличить индекс
                        IF (NUMB GT 9)
                        NUMB = 0
                        HIGHBYTE = HIGHBYTE + 10H
                        ENDIF
                        IF (HIGHBYTE GT 90H)
                        EXITM
                        ENDIF
                      BCDNUMB = (NUMB OR HIGHBYTE)
                      DW    BCDNUMB ;;определить слово с именем NUMB
                      ENDM          ;;конец команды REPT
                    ENDM            ;;конец макро

            Теперь в листинге наше макро выглядит так:

            31                   @BCDtabel   20
            32 0004          1   BCD1to20  label word ;определить метку
            33 0004  0001    2       DW    BCDNUMB         ;
            34 0006  0002    2       DW    BCDNUMB         ;
            35 0008  0003    2       DW    BCDNUMB         ;
            и т.д.

            Знак амперсанда  (&)  сообщает MASM о необходимости подставить
         значение N,  используемое при инициировании макро.  Но и это  нас
         еще  не  удовлетворяет.  Наличие  у списка чисел BCD только одной
         метки заставляет нас для доступа к списку  использовать  индекс.
         Мы бы хотели иметь метку у каждого элемента списка.  Оператор вы-
         ражения %  позволит нам иметь значение каждого числа и  использо-
         вать его как часть метки.  Мы переписываем наше макро в виде двух
         следующих макро:

            @BCD     MACRO      NAME,NUMBER    ;;NAME для метки
                            ;;NUMBER для данных
                     BCDof&NAME     DW  NUMBER ;;определить слово с
                                    ;;NUMBER в коде BCD
                     ENDM           ;;конец макро
            ;;
            @BCDtable MACRO N  ;;определить макро с параметром N
                     NUMB  = 0 ;;инициализировать числа
                     INDEX = 0
                     HIGHBYTE        = 0
                       REPT N   ;;повторить нижеследующее N раз
                       INDEX = INDEX + 1
                       NUMB  = NUMB + 1   ;;увеличить индекс
                         IF (NUMB GT 9)
                       NUMB        = 0
                       HIGHBYTE = HIGHBYTE + 10H
                       ENDIF
                       IF (HIGHBYTE  GT 90H)
                       EXITM
                       ENDIF
                       BCDNUMB = (NUMB OR HIGHBYTE)
                       @BCD %INDEX,BCDNUMB    ;;INDEX для метки
                                 ;;BCDNUMBER для данных
                       ENDM      ;;конец команды REPT
                     ENDM        ;;конец макро


                                      - 1-48 -

            Теперь, когда  мы смотрим листинг,  мы видим,  что каждый байт
         таблицы чисел BCD имеет соответствующую метку:

                        @BCDtable  20
            0004  0001   3 BCDof1  DW  BCDNUMB  ;определить число с
            0006  0002   3 BCDof2  DW  BCDNUMB  ;      NUMBER
            0008  0003   3 BCDof3  DW  BCDNUMB  ;        в
            000A  0004   3 BCDof4  DW  BCDNUMB  ;   коде BCD
            .
            .
            .

            Таким образом можно создавать сложные таблицы.Если есть форму-
         ла типа (N x M)/((P+Q) MOD T),  вместо ручного заполнения таблицы
         мы можем поручить заботы по ее созданию MASM.
            Проверять ситуацию переполнения мы могли бы,  включив в  текст
         нашего макро что-нибудь вроде следующего:

            IFE (BCDNUMB LE 0FFFFh) ;;больше, чем может хранить слово?
            DW      BCDNUMB         ;;достаточно мало
            ELSE
            %OUT ERROR IN @BCD MACRO

            Оператор OUT выводит сообщение на экран во время ассемблирова-
         ния  -  в данном случае сообщение "ERROR IN @BCD MACRO" (ошибка в
         макро @BCD).
            До сих пор мы использовали параметры, как конкретные элементы,
         разделенные запятыми. В качестве одиночного параметра макро также
         возможно иметь набор элементов,  который будет использоваться для
         итеративного создания данных.  Например, если мы хотим установить
         список сообщений,  подлежащих выводу на экран, мы можем закодиро-
         вать макронабор:

            @OptDisp MACRO OptType,Options ;; OptType = метка,
                                           ;; Options = список
            OptType&List     db   Options
            ENDM                           ;;конец макро

         Затем мы можем использовать егo в сегменте данных:

            @OptDisp LineSpeed,<'1200sq],'2400','4800'>

            Linespeed - будет заменено в метке,  и каждая строка в угловых
         скобках будет вставлена в директиву db, как если мы набрали:

            LineSpeedList   db      '1200'
                            db      '2400'
                            db      '4800'

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


                                      - 1-49 -
            @MakeList MACRO Name2,messag
                    MESSAGE&Name2    db   CR,LF,messag,CR,LF,0
                    ENDM
            ;;
            @OptDisp MACRO Options ;;OptType = метка,Options =  список
                    Name3 = 0
                      IRP msg,
                      Name3 = Name3 + 1
                      @MakeList %Name3,msg
                      ENDM
                    ENDM             ;;конец макро
            Строки сегмента данных мы можем использовать так:

            @OptDisp <'Error','Waiting','Computing'>

            Каждая строка в угловых скобках будет помещаться в дирeк-
         тиву db, как показано в следующем фрагменте листинга:

                              @OptDisp <'Error','Waiting','Computing'>
           0D 0A 45 72 72 6F 72 3 MESSAGE1 db CR,LF,'ERROR',CR,LF,0
           0D 0A 57 61 69 74 69 3 MESSAGE2 db CR,LF,'Waiting',CR,LF,0
           0D 0A 43 6F 6D 70 75 3 MESSAGE3 db CR,LF,'Computing',CR,LF,0
            Поучительным моментом данного макро является то,  что для соз-
         дания необходимого числа строк мы использовали  в  директиве  IRP
         оператор  литерального  текста  (<  >).Однако у нас еще не решена
         проблема доступа к этому списку строк. Нам необходим список адре-
         сов. Следующее макро представляет решение этой проблемы.
            @MakeList МACRO Name2,messag
                    MESSAGE&Name2   db    CR,LF,messag,CR,LF,0
                    ENDM
            ;;
            @MakeNames  MACRO Name5
                    db       MESSAGE&Name5
                    ENDM                   ;;конец REPT
            ;;
            @OptDisp MACRO Options ;;OptType =  метка, Options = список
                    Name3 = 0
                      IRP   msg,
                      Name3 = Name3 + 1
                      @MakeList  %Name3,msg
                      ENDM
                      Name4 = 0
                      MessageList Label WORD
                        REPT Name3
                        Name4 = Name4 + 1
                        @MakeNames  %Name4
                        ENDM                  ;;конец REPT
                      ENDM                    ;;конец макро
            Когда макро  используется  в секции данных,  мы получим тот же
         результат, как если бы набрали следующее:
            @OptDisp  <'Error','Waiting','Computing'>
            MESSAGE1    db   CR,LF,'Error',CR,LF,0
            MESSAGE2    db   CR,LF','Waiting',CR,LF,0
            MESSAGE3    db   CR,LF,'Computing',CR,LF,0
            MessageList Label   WORD
            dw      MESSAGE1
            dw      MESSAGE2
            dw      MESSAGE3

                                      - 1-50 -
            Конечно, для генерации  данных  при помощи макро можно сделать
         гораздо больше.  Мы лишь подбросили идею некоторых  возможностей.
         Те  же  методы могут быть использованы для генерации программного
         кода, что мы теперь и рассмотрим.

                        Макросы генерации программного кода
            Макросы представляют собой мощный механизм передачи ассемблеру
         некоторых действий по программированию.  Также, как Вы можете пи-
         сать программу на Бейсике,  заставляющую  компьютер выполнять за-
         данную Вами работу,  Вы можете написать программу на МAСRO,  зас-
         тавляющую  ассемблер,  в  данном  случае MASM,  выполнять для Вас
         неинтересную часть работы по программированию.  Ниже,  в качестве
         упрощенного примера того,  что мы имели в виду,  приведено макро,
         реализующее запись символа в файл:
Предыдущая страница Следующая страница
1 ... 9 10 11 12 13 14 15  16 17 18 19 20 21 22 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама