Главная · Поиск книг · Поступления книг · 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
Образование - Питер Абель Весь текст 992.61 Kb

Ассемблер и программирование для IBM PC

Предыдущая страница Следующая страница
1 ... 55 56 57 58 59 60 61  62 63 64 65 66 67 68 ... 85
IFB <аргумент>           Если  аргументом   является   пробел,   ассемблер
                         обрабатывает операторы в условном блоке. Аргумент
                         должен быть в угловых скобках.
IFNB <аргумент>          Если аргументом является не пробел,  то ассемблер
                         обрабатывает операторы в условном блоке. Аргумент
                         должен быть в угловых скобках.
IFIDN <арг-1>,<арг-2>    Если строка  первого  аргумента  идентична строке
                         второго аргумента,   то   ассемблер  обрабатывает
                         операторы в условном блоке. Аргументы должны быть
                         в угловых скобках.
IFDIF<арг-1>,<арг-2>     Если  строка  первого  аргумента  отличается   от
                         строки второго     аргумента,     то    ассемблер
                         обрабатывает   операторы   в   условном    блоке.
                         Аргументы должны быть в угловых скобках.

     Ниже приведен простой пример директивы IFNB (если не пробел). Для DOS
INT 21H все запросы требуют занесения номера функции в регистр  AH,  в  то
время как лишь  некоторые  из  них  используют  значение  в  регистре  DX.
Следующее макроопределение учитывает эту особенность:

               DOS21     MACRO     DOSFUNC,DXADDRES
                         MOV       AN,DOSFUNC
                         IFNB      
                         MOV       DX,OFFSET DXADDRES
                         ENDIF
                         INT       21H
                         ENDM

     Использование DOS21 для простого ввода с клавиатуры требует установки
значения 01 в регистр AH:

                         DOS21     01

Ассемблер генерирует в результате команды MOV AH,01 и INT 21H.  Для  ввода
символьной строки требуется занести в регистр AH значение 0AH, а в регистр
DX - адрес области ввода:

                         DOS21     0AH,IPFIELD

Ассемблер генерирует в результате обе команды MOV и INT 21H.


     ДИРЕКТИВА ВЫХОДА ИЗ МАКРОСА EXITM.
     ________________________________________________________________

     Макроопределение  может  содержать  условные    директивы,    которые
проверяют важные  условия.  Если  условие  истинно,  то  ассемблер  должен
прекратить дальнейшее макрорасширение.  Для  этой  цели  служит  директива
EXITM:

               IFxx      [условие]
               .
               .         (неправильное условие)
               .
               EXITM
               .
               .
               ENDIF

     Как только ассемблер попадает в процессе генерации макрорасширения на
директиву  EXITM,  дальнейшее  расширение   прекращается    и    обработка
продолжается  после  директивы  ENDM.  Можно  использовать    EXITM    для
прекращения повторений по директивам  REPT,  IRP  и  IRPC  даже  если  они
находятся внутри макроопределения.


     МАКРОКОМАНДЫ, ИСПОЛЬЗУЮЩИЕ IF И IFNDEF УСЛОВИЯ
     ________________________________________________________________

     Программа  на  рис.20.6  содержит  макроопределение  DIVIDE,  которая
генерирует подпрограмму для выполнения  деления  вычитанием.  Макрокоманда
должна кодироваться с параметрами в следующей последовательности: делимое,
делитель, частное.  Макрокоманда содержит директиву  IFNDEF  для  проверки
наличия  параметров.  Для  любого  неопределенного  элемента  макрокоманда
увеличивает счетчик CNTR.  Этот счетчик может иметь любое корректное имя и
предназначен  для  временного  использования  в  макроопределении.   После
проверки всех трех параметров, макрокоманда проверяет CNTR:

                    IF   CNTR
                    ;Макрорасширение прекращено
                    EXITM

     Если  счетчик  CNTR  содержит  ненулевое  значение,   то    ассемблер
генерирует  комментарий  и  прекращает  по  директиве  EXITM    дальнейшее
макрорасширение.  Заметим, что начальная команда устанавливает в  счетчике
CNTR нулевое значение и, кроме того, блоки IFNDEF  могут  устанавливать  в
CNTR единичное значение, а не увеличивать его на 1.
     Если ассемблер  успешно  проходит  все  проверки,  то  он  генерирует
макрорасширение.  В кодовом сегменте первая макрокоманда  DIVIDE  содержит
правильные делимое и частное и,  поэтому  генерирует  только  комментарии.
Один из  способов  улучшения  рассматриваемой  макрокоманды  -  обеспечить
проверку на ненулевой делитель и на одинаковый знак делимого  и  делителя;
для этих целей лучше использовать коды ассемблера, чем условные директивы.

__________________________________________________________________________

                         TITLE   MACRO6 (COM) Проверка директ. IF и IFNDEF
                         ; -----------------------------------------------
                         DIVIDE  MACRO   DIVIDEND,DIVISOR,QUOTIENT
                                 LOCAL   COMP
                                 LOCAL   OUT
                                 CNTR    = 0
                         ;       AX-делимое, BX-делитель, CX-частное
                                 IFNDEF  DIVIDEND
                         ;               Делитель не определен
                                 CNTR    = CNTR +1
                                 ENDIF
                                 IFNDEF  DIVISOR
                         ;               Делимое не определено
                                 CNTR    = CNTR +1
                                 ENDIF
                                 IFNDEF  QUOTIENT
                         ;               Частное не определено
                                 CNTR    = CNTR +1
                                 ENDIF
                                 IF      CNTR
                         ;               Макрорасширение отменено
                                 EXITM
                                 ENDIF
                                 MOV     AX,DIVIDEND   ;Загрузка делимого
                                 MOV     BX,DIVISOR    ;Загрузка делителя
                                 SUB     CX,CX       ;Регистр для частного
                         COMP:
                                 CMP      AX,BX      ;Делимое < делителя?
                                 JB       OUT        ; да - выйти
                                 SUB      AX,BX        ;Делимое - делитель
                                 INC      CX           ;Частное + 1
                                 JMP      COMP
                         OUT:
                                 MOV      QUOTIENT,CX  ;Запись результата
                                 ENDM
                         ; -----------------------------------------------
0000                     CSEG    SEGMENT  PARA 'Code'
                                 ASSUME   CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
0100                             ORG      100H
0100  EB 06              BEGIN:  JMP      SHORT MAIN
                         ; -----------------------------------------------
0102  0096               DIVDND  DW       150
0104  001B               DIVSOR  DW       27
0106  ????               QUOTNT  DW       ?
                         ; -----------------------------------------------
0108                     MAIN    PROC     NEAR
                                 .LALL
                                 DIVIDE   DIVDND,DIVSOR,QUOTNT
= 0000                 +         CNTR    = 0
                       + ;       AX-делимое, BX-делитель, CX-частное
                       +         ENDIF
                       +         ENDIF
                       +         ENDIF
                       +         ENDIF
0108  A1 0102 R        +         MOV     AX,DIVDND     ;Загрузка делимого
0108  8B 1E 0104 R     +         MOV     BX,DIVSOR     ;Загрузка делителя
010F  2B C9            +         SUB     CX,CX       ;Регистр для частного
0111                   + ??0000:
0111  3B C3            +         CMP     AX,BX       ;Делимое < делителя?
0113  72 05            +         JB      ??0001      ; да - выйти
0115  2B C3            +         SUB     AX,BX         ;Делимое - делитель
0117  41               +         INC     CX
0118  EB F7            +         JMP     ??0000
011A                   + ??0001:
011A  89 0E 0106 R     +         MOV     QUOTNT,CX     ;Запись результата
                                 DIVIDE  DIDND,DIVSOR,QUOT
= 0000                 +         CNTR    = 0
                       + ;       AX-делимое, BX-делитель, CX-частное
                       +         IFNDEF  DIDND
                       + ;               Делитель не определен
= 0001                 +         CNTR    = CNTR +1
                       +         ENDIF
                       +         ENDIF
                       +         IFNDEF  QUOT
                       + ;               Частное не определено
= 0002                 +         CNTR    = CNTR +1
                       +         ENDIF
                       +         IF      CNTR
                       + ;               Макрорасширение отменено
                       +         EXITM
011E  C3                         RET
011F                     MAIN    ENDP
011F                     CSEG    ENDS
                                 END    BEGIN
__________________________________________________________________________

     Рис.20.6. Использование директив IF и IFNDEF.


     МАКРОС, ИСПОЛЬЗУЮЩИЙ IFIDN-УСЛОВИЕ
     ________________________________________________________________

     Программа на  рис.20.7  содержит  макроопределение  по  имени  MOVIF,
которая генерирует команды MOVSB или MOVSW  в  зависимости  от  указанного
параметра.  Макрокоманду можно кодировать с параметром B (для байта) или W
(для слова) для генерации команд MOVSB или MOVSW из MOVS.
     Обратите внимание на первые два оператора в макроопределении:

               MOVIF     MACRO     TAG
                         IFIDN     <&TAG>,

Условная директива IFIDN сравнивает заданный параметр (предположительно  B
или W) со строкой B.  Если значения идентичны, то ассемблер генерирует REP
MOVSB.  Обычное использование амперсанда (&)  -  для  конкатенации,  но  в
данном примере операнд  без амперсанда  не  будет  работать.  Если  в
макрокоманде не будет указан параметр B или W,  то  ассемблер  сгенерирует
предупреждающий комментарий и команду MOVSB (по умолчанию).
     Примеры в кодовом сегменте трижды проверяют макрокоманду  MOVIF:  для
параметра B, для параметра W и для  неправильного  параметра.  Не  следует
делать попыток выполнения данной программы в том виде, как  она  приведена
на рисунке, так как регистры CX и DX не обеспечены правильными значениями.
     Предполагается, что рассматриваемая макрокоманда  не  является  очень
полезной и ее назначение здесь - проиллюстрировать  условные  директивы  в
простой форме.  К данному моменту, однако, вы имеете достаточно информации
для составления больших полезных макроопределений.

__________________________________________________________________________

                             TITLE   MACRO7 (COM) Проверка директивы IFIDN
                             ; -------------------------------------------
                             MOVIF   MACRO   TAG
                                     IFIDN   <&TAG>,
                                     REP MOVSB
                                     EXITM
                                     ENDIF
                                     IFIDN   <&TAG>,
                                     REP MOVSW
                                     ELSE
                             ;       Не указан параметр B или W,
                             ;           по умолчанию принято B
                                     REP MOVSB
                                     ENDIF
                                     ENDM
                             ; -------------------------------------------
0000                         CSIG    SEGMENT PARA 'Code'
Предыдущая страница Следующая страница
1 ... 55 56 57 58 59 60 61  62 63 64 65 66 67 68 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама