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

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


    Прохождения игр    
StarCraft II Wings of Liberty |#10| Страшная Правда
StarCraft II: Wings of Liberty |#9| Шепот Судьбы
StarCraft II: Wings of Liberty |#8| Большие раскопки
Minecraft |#3| Сборная солянка и новый мир

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


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

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

Предыдущая страница Следующая страница
1 2 3 4 5  6 7 8 9 10 11 12 13 14 ... 198
         MASM,  которая не вырабатывает собственного кода;  таким образом,
         он в листинге отсутствует. С другой стороны, директивы завершения
         сегмента ENDS приводятся в листинге,  хотя программный код не вы-
         рабатывают. Есть в MASM тайны, над которыми всем нам стоит пораз-
         мышлять.
            Представленную программу не следует рассматривать,  как эталон
         хорошего  программирования.  Хотя  идея  использования макросов в
         вводной и  заключительной  части  .EXE-программ  и  замечательна,
         включение  имен "важных" символов в сами макросы применяется ред-
         ко.  Если имя сегмента данных отличается от dat _seg, в программе
         может  возникнуть  нежелательная конфликтная ситуация.  Например,
         когда макро @TypeStr должно передать имя dat_seg в качестве аргу-

                                      - 1-9 -
         мента или макро @InitPrg полагает,  что сегмент данных называется
         dat_seg.

                             Директивы листинга макро

            Если вы хотите увидеть полный листинг макро,  поместите в файл
         с  ассемблерной  программой директиву MASM .LALL.  Затем получите
         файл .LST и сравните его с первоначальным листингом нашего приме-
         ра.  Теперь оператор ASSUME ds:data_seg будет в листинге. Для из-
         менения режима листинга на обратный используйте  директиву .XALL.
         Она  вернет MASM в режим,  устанавливаемый по умолчанию.  Если Вы
         хотите подавить все макрорасширения, используйте директиву .SALL.


                                  Макробиблиотеки

            Термин "макробиблиотека" не совсем верен.  В действительности,
         макробиблиотеки совсем не то,  что под  этим  могли  бы  понимать
         программные средства LINK /редактор/ и LIB /обработчик библиотек/
         фирмы Майкрософт.Макросы должны подключаться во время компиляции,
         так  как  они  представляют собой директивы для MASM и только для
         MASM.  Средства LINK и LIB не знают,  что делать с  ними.  Вместо
         этого макробиблиотеки являют собой файлы типа include (включить).
         Они могут определяться в отдельном  файле,  называемом  MYLIB.MAC
         или  STANDARD.  MLB  или как-нибудь еще  (Вы можете выбрать любое
         допустимое имя), и подключаться при  ассемблировании  посредством
         помещения в исходный текст программы директивы include. Например,

             INCLUDE  C:\ASМ\LIB\STANDARD.MLB

            Правила написания имени и указания накопителя те же, что и для
         всей  системы.  В  файле  листинга  строки,  полученные  из файла
         include, начинаются с буквы "C", равно как строки макрорасширения
         начинаются с плюса "+" (в версиях MASM ниже 4.0) или номера уров-
         ня расширения. Конечно, если у Вас большая библиотека и Вы не хо-
         тите загромождать файл .LST макроописаниями, при помощи директивы
         .XLIST "выключите" листинг перед include,  а затем "включите" его
         обратно (после include),  применяя директиву .LIST.
            Использование макробиблиотек  обосновывает  введение следующих
         макродиректив.  Хотя довольно редко сначала  определяют  макро  в
         программе,  а  затем отменяют такое определение (Вы бы его скорее
         просто уничтожили!),  для использования нескольких макроопределе-
         ний Вы вполне можете подключить макробиблиотеку.  Оставшиеся мак-
         роопределения занимают значительное пространство памяти в таблице
         символов MASM и в области памяти макро.  Вернуть эту память можно
         при помощи директивы PURGE  (очистить).  PURGE  позволяет  изъять
         описания  указанных макро.  Для изъятия макроописаний предыдущего
         примера следует выдать директиву:

            PURGE @DosCall,@InitStk,@InitPrg,@Finis,@DisStr,@TypeStr

            Она очищает все пространство памяти,  занятое макроописаниями,
         и позволяет нам использовать его для других целей.





                                      - 1-10 -
                         Макродиректива повторения - REPT

            MASM обеспечивает возможность повторять  блок  макрокода.  Су-
         ществует  три  варианта повтора,  причем каждый из них имеет свое
         особое предназначение.
            В качестве первого примера предположим, что мы хотим создать в
         сегменте данных область для обработки файлов. Для получения досту-
         па к файлам мы используем метод описателя  файла и, так как мы хо-
         тим работать более чем с одним файлом, мы пишем программу, присва-
         ивая каждому блоку уникальное имя.

            file_head    MACRO       fnum
            file_hand_&fnum   dw     ?     ;заголовок файла
            file_nmax_&fnum   db     49    ;макс.длина имени файла
            file_nlen_&fnum   db     ?     ;действит.длина имени файла
            file_name_&fnum   db     50 dup (?) ;буфер имени файла
                           ENDM

            Почему для fnum (номер файла)  мы  не  использовали  директиву
         LOCAL? Потому, что для самого макро эти метки не являются локаль-
         ными.  К ним должен осуществляться доступ из других частей  прог-
         раммы с целью установки имени файла, получения возможности опери-
         рования с блоком управления файлом и т.д.  Это макро  может  быть
         усовершенствовано.  Что необходимо сообщить программе пофайлового
         копирования,  если мы хотим одновременно обрабатывать два  файла?
         Нам следует дважды вызвать file_head (описатель файла):

            file_head       1      ;1-ый блок файла
            file_head       2      ;2-ой блок файла

            Вместо этого,  используя директиву REPT (повторить),  мы можем
         написать file_head так, чтобы он определял столько блоков, сколь-
         ко необходимо. Такой макрос приведен в Листинге 1-3.

                    Листинг 1-3. Описание блока доступа к файлу
            ------------------------------------------------------------

            fcnt           =            0  ;определить и иниц-ать символ
            file_head2     MACRO       fnum
            file_hand_&fnum     dw      ?      ;заголовок файла
            file_nmax_&fnum     db      49     ;макс.длина имени файла
            file_nlen_&fnum     db      ?      ;действ.длина имени файла
            file_name_&fnum     db      50 dup (?)  ;буфер имени файла
                           ENDM
            file_head      MACRO        fnum
                           REPT         fnum   ;повторить блок "fnum" раз
                           file_head2   %fcnt  ;создать блок  #"fcnt"
            fcnt           =    fcnt + 1
                           ENDM                ;закончить блок повторения
                           ENDM                ;закончить макро file_head
            -------------------------------------------------------------

            Как показано в Листинге 1-4, при вызове макро file_head оно, в
         свою очередь, дважды вызывает макро file_head2,  используя каждый
         раз новое значение fnum. Конечно, это макрорасширение со значени-
         ем статуса листинга,  установленного по умолчанию,  не показывает
         явно обращения к file_head2.  Однако результат работы REPT мы мо-
         жем  видеть по двум созданным блокам управления файлами. Заметим,

                                      - 1-11 -
         что директива REPT должна заканчиваться строкой ENDM, равно как и
         директива MACRO. Вcе блоки повторения должны  заканчиваться  ENDM
         (конец макро). Аналогично ENDM должно появляться в конце  каждого
         макроопределения.

           Листинг 1-4.  Макрорасширение блока описания доступа к файлу
         -----------------------------------------------------------------

                         file_head 2
            3       file_hand_0    dw   ?    ;заголовок файла
            3       file_nmax_0    db   49   ;макс. длина имени файла
            3       file_nlen_0    db   ?    ;действит.длина имени файла
            3       file_name_0    db   50 dup (?)  ;буфер имени файла
            3       file_hand_1    dw   ?    ;заголовок файла
            3       file_nmax_1    db   49   ;макс. длина имени файла
            3       file_nlen_1    db   ?    ;действит.длина имени файла
            3       file_name_1    db   50 dup (?)  ;буфер имени файла
         ------------------------------------------------------------------

            В добавление к директиве REPT мы также  использовали  счетчик.
         Счетчик - это переменная,  имеющая цифровое значение. Так как его
         значение может меняться, он должен быть определен при помощи опе-
         ратора присваивания (=). (В MASM для определения переменных, име-
         ющих статические значения,  используется  оператор  equ  (прирав-
         нять),  в  то время как для определения переменных,  чьи значения
         могут изменяться,  применяется знак равенства (=).) Счетчик, при-
         меняемый  в  макро  file_head,  называется  fcnt (счетчик файла).
         Счетчик fcnt увеличивается на 1 при каждом проходе  file_head. Но
         почему метки находятся в file_head2,  file_hand_0 и т.д.,  а не в
         file_hand_fcnt?  Каким образом имя fcnt заменяется на свое значе-
         ние?   Ответ   заключается   в  операторе  "%",стоящем  в  вызове
         file_head2 перед fcnt.  Знак процента предписывает замену символа
         на его значение. Так как мы использовали знак процента, нам необ-
         ходимы два макро.  Если бы мы попытались вычислить  и  подставить
         fcnt в одно маkро:

                            REPT      fnum   ;повторить блок "fnum" раз
            file_hand_&%fcnt       dw   ?         ;заголовок файла   ,

            возникла бы ошибка символа:


            file_hand_fcnt         dw   ?         ;заголовок файла

            Оператор процента (%) работает только в аргументах  макровызо-
         ва! Кроме того, значение символа должно быть абсолютной  (непере-
         мещаемой) константой.
            Другим важным  аспектом  наших макро является то,  что счетчик
         fcnt инициализируется вне макроблока. Это делается потому, что мы
         не хотим устанавливать  fcnt  в 0 всякий раз при вызове file_head
         (что может вызвать дублирование меток). Однако,  fcnt должен быть
         где-то инициализирован, или оператор:

            fcnt       =           fcnt +  1


                                      - 1-12 -
         вызовет появление сообщения об ошибке "Символ не определен".


             Более подробно о макродирективах повторения - IRP и IRPC

            Кроме директивы  REPT MASM поддерживает еще две директивы мак-
         роповторений.  Это - IRP (неограниченное повторение) и IRPC  (не-
         ограниченное повторение символа).  В действительности,  ничто не
         повторяется бесконечно. Вместо этого повторения происходят до тех
         пор, пока в списке аргументов есть хоть один аргумент. В Листинге
         1-5 приведен пример макроповторения,  названного test_vac и пред-
         назначенного для добавления элементов в сегмент данных.

             Листинг 1-5. Пример макро повторения IRP и его расширение
         ------------------------------------------------------------------

            test_mac    MACRO     args            ;определить "test_mac"
                        IRP       dummy,<&args>
                        db        dummy           ;добавить элемент
                        ENDM                      ;закончить "IRP"
                        ENDM                      ;закончить "test_mac"

                        test_mac   'one'                <-- 1-ый вызов
            2           db         'one'          ;добавить элемент
Предыдущая страница Следующая страница
1 2 3 4 5  6 7 8 9 10 11 12 13 14 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама