Главная · Поиск книг · Поступления книг · 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 ... 12 13 14 15 16 17 18  19 20 21 22 23 24 25 ... 85
регистра.  Например, при  сравнении  содержимого  двух  полей  последующий
переход зависит от значения флага.
     Команду LOOP в программе на рис.7.2 можно заменить  на  две  команды:
одна  уменьшает  содержимое  регистра  CX,  а  другая  выполняет  условный
переход:

          Использование LOOP    Использование условного перехода

                 LOOP A20                 DEC  CX
                                          JNZ  A20

     Команды DEC  и  JNZ  действуют  аналогично  команде  LOOP:  уменьшают
содержимое регистра CX на 1 и выполняет переход на метку A20, если в CX не
ноль.  Команда DEC кроме того устанавливает флаг нуля во флаговом регистре
в состояние 0  или  1.  Команда  JNZ  затем  проверяет  эту  установку.  В
рассмотренном  примере  команда  LOOP   хотя    и    имеет    ограниченное
использование, но более эффективна, чем две команды: DEC и JNZ.
     Аналогично командам  JMP  и  LOOP  операнд  в  команде  JNZ  cодержит
значение расстояния между  концом  команды  JNZ  и  адресом  A20,  которое
прибавляется к командному указателю. Это расстояние должно быть в пределах
от -128 до +127 байт.  В случае перехода за эти границы  ассемблер  выдаст
сообщение "Relative jump out of range"  (превышены  относительные  границы
перехода).


                      Знаковые и беззнаковые данные
                     -------------------------------
     Рассматривая назначение команд условного  перехода  следует  пояснить
характер  их  использования.  Типы  данных,  над   которыми    выполняются
арифметические операции и операции сравнения определяют  какими  командами
пользоваться: беззнаковыми или знаковыми.  Беззнаковые  данные  используют
все биты как биты данных; характерным примером являются символьные строки:
имена, адреса и натуральные числа.  В  знаковых  данных  самый  левый  бит
представляет собой знак, причем если его значение  равно  нулю,  то  число
положительное, и если единице, то отрицательное.  Многие числовые значения
могут быть как положительными так и отрицательными.
     В качестве примера предположим, что регистр AX содержит  11000110,  а
BX - 00010110. Команда

                         CMP  AX,BX

сравнивает содержимое регистров AX  и  BX.  Если  данные  беззнаковые,  то
значение в AX больше, а если знаковые - то меньше.


                     Переходы для беззнаковых данных
                    ---------------------------------
          Мнемоника      Описание                      Проверяемые флаги

          JE/JZ     Переход, если равно/нуль                     ZF
          JNE/JNZ   Переход, если не равно/не нуль               ZF
          JA/JNBE   Переход, если выше/не ниже или равно         ZF,CF
          JAE/JNB   Переход, если выше или равно/не ниже         CF
          JB/JNAE   Переход, если ниже/не выше или равно         CF
          JBE/JNA   Переход, если ниже или равно/не выше         CF,AF

     Любую проверку можно кодировать одним из  двух  мнемонических  кодов.
Например, JB  и  JNAE  генерирует  один  и  тот  же  объектный  код,  хотя
положительную проверку JB легче понять, чем отрицательную JNAE.


                       Переходы для знаковых данных
                      ------------------------------
          Мнемоника      Описание                      Проверяемые флаги

          JE/JZ     Переход, если равно/нуль                     ZF
          JNE/JNZ   Переход, если не равно/не нуль               ZF
          JG/JNLE   Переход, если больше/не меньше или равно     ZF,SF,OF
          JGE/JNL   Переход, если больше или равно/не меньше     SF,OF
          JL/JNGE   Переход, если меньше/не больше или равно     SF,OF
          JLE/JNG   Переход, если меньше или равно/не больше     ZF,SF,OF

     Команды перехода для условия равно или ноль (JE/JZ) и не равно или не
ноль (JNE/JNZ) присутствуют в обоих списках  для  беззнаковых  и  знаковых
данных. Состояние равно/нуль происходит вне зависимости от наличия знака.


                   Специальные арифметические проверки
                  -------------------------------------
          Мнемоника      Описание                      Проверяемые флаги

          JS        Переход, если есть знак (отрицательно)       SF
          JNS       Переход, если нет знака(положительно)        SF
          JC        Переход, если есть перенос (аналогично JB)   CF
          JNC       Переход, если нет переноса                   CF
          JO        Переход, если есть переполнение              OF
          JNO       Переход, если нет переполнения               OF
          JP/JPE    Переход, если паритет четный                 PF
          JNP/JP    Переход, если паритет нечетный               PF

     Еще одна команда условного перехода  проверяет  равно  ли  содержимое
регистра  CX  нулю.  Эта  команда  необязательно   должна    pасполагаться
непосредственно за командой арифметики или сравнения.  Одним из  мест  для
команды JCXZ может быть  начало  цикла,  где  она  проверяет  содержит  ли
регистр CX ненулевое значение.
     Не спешите пока заучивать эти команды наизусть. Запомните только, что
для беззнаковых данных есть переходы по состояниям равно, выше или ниже, а
для беззнаковых - равно, больше или меньше.  Переходы по проверкам  флагов
переноса, переполнения  и  паритета  имеют  особое  назначение.  Ассемблер
транслирует мнемонические коды в объектный код независимо от  того,  какую
из двух команд вы применили.  Однако,  команды  JAE  и  JGE  являясь  явно
одинаковыми, проверяют различные флаги.


     ПРОЦЕДУРЫ И ОПЕРАТОР CALL
     ________________________________________________________________

     В предыдущих главах примеры содержали в кодовом сегменте только  oдну
процедуру, оформленную следующим образом:

               BEGIN     PROC FAR
                    .
                    .
               BEGIN     ENDP

     Операнд FAR информирует систему о  том,  что  данный  адрес  является
точкой входа для выполнения, а директива ENDP определяет конец  процедуры.
Кодовый  сегмент,  однако,  может  содержать  любое  количество  процедур,
которые  разделяются  директивами  PROC  и  ENDP.  Типичная    организация
многопроцедурной программы приведена на рис.7.3.

__________________________________________________________________________

                        ЪДДДДДДДДДДДДДДДДДДДДДДДД¬
                        ¦ CODESG  SEGMENT  PARA  ¦
                        ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                        ¦ BEGIN   PROC     FAR   ¦
                        ¦          .             ¦
                        ¦          .             ¦
                        ¦         CALL     B10   ¦
                        ¦         CALL     C10   ¦
                        ¦         RET            ¦
                        ¦ BEGIN   ENDP           ¦
                        ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                        ¦ B10     PROC     NEAR  ¦
                        ¦          .             ¦
                        ¦          .             ¦
                        ¦         RET            ¦
                        ¦ B10     ENDP           ¦
                        ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                        ¦ C10     PROC     NEAR  ¦
                        ¦          .             ¦
                        ¦          .             ¦
                        ¦         RET            ¦
                        ¦ C10     ENDP           ¦
                        ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                        ¦ CODESG  ENDS           ¦
                        ¦         END      BEGIN ¦
                        АДДДДДДДДДДДДДДДДДДДДДДДДЩ
__________________________________________________________________________

     Рис.7.3. Вызов процедур.


     Обратите внимание на следующие особенности:

          - Директивы PROC по меткам B10 и  C10  имеют  операнд  NEAR  для
     указания  того,  что  эти  процедуры  находятся  в  текущем   кодовом
     сегменте. Во многих последующих примерах этот операнд опущен, так как
     по умолчанию ассемблер принимает тип NEAR.

          - Каждая процедура имеет уникальное имя и  содержит  собственную
     директиву ENDP для указания конца процедуры.

          - Для передачи управления в процедуре BEGIN имеются две команды:
     CALL B10 и CALL C10. В  результате  первой  команды  CALL  управление
     передается процедуре  B10  и  начинается  ее  выполнение.   Достигнув
     команды  RET,  управление  возвращается  на  команду  непосредственно
     следующую за CALL B10.  Вторая команда CALL  действует  аналогично  -
     передает   управление   в  процедуру  C10,  выполняет  ее  команды  и
     возвращает управление по команде RET.

          - Команда RET всегда выполняет возврат в  вызывающую  программу.
     Программа BEGIN вызывает процедуры  B10  и  C10,  которые  возвращают
     управление обратно в BEGIN.  Для  выполнения  самой  программы  BEGIN
     операционная система DOS вызывает ее и в конце выполнения команда RET
     возвращает  управление  в  DOS.  Если  процедура  B10  не    содержит
     завершающей команды  RET,  то  выполнение  команд  продолжится из B10
     непосредственно в процедуре  C10.  Если  процедура  C10  не  содержит
     команды RET,  то будут выполняться команды, оказавшиеся за процедурой
     C10 с непредсказуемым результатом.

     Использование  процедур  дает  хорошую    возможность    организовать
логическую структуру программы.  Кроме того,  операнды  для  команды  CALL
могут иметь значения, выходящие за границу от -128 до +127 байт.
     Технически управление в процедуру типа NEAR  может  быть  передано  с
помощью команд перехода или даже обычным  построчным  кодированием.  Но  в
большинстве случаев рекомендуется использовать команду CALL  для  передачи
управления в процедуру и команду RET для возврата.


     СЕГМЕНТ СТЕКА
     ________________________________________________________________

     До  этого  раздела  в  приводимых  примерах  встретились  только  две
команды, использующих стек, - это команды PUSH в  начале  сегмента  кодов,
которые обеспечивают  возврат  в  DOS,  когда  EXE-программа  завершается.
Естественно для этих программ требуется стек oчень малого размера. Однако,
команда CALL автоматически записывает в стек относительный адрес  команды,
следующей непосредственно за командой  CALL,  и  увеличивает  после  этого
указатель вершины стека.  В вызываемой процедуре  команда  RET  использует
этот адрес для возврата в вызывающую процедуру и  при  этом  автоматически
уменьшается указатель вершины стека.
     Таким образом, команды PUSH записывают в стек двухбайтовые адреса или
другие значения.  Команды POP обычно выбирают из стека записанные  в  него
слова.  Эти операции изменяют относительный адрес в регистре  SP  (т.е.  в
указатели стека) для доступа к следующему  слову.  Данное  свойство  стека
требует чтобы команды RET и CALL соответствовали друг другу.  Кроме  того,
вызванная процедура может вызвать с помощью команды CALL другую процедуру,
а та в свою очередь - следующую. Стек должен иметь достаточные размеры для
того, чтобы хранить  все  записываемые  в  него  адреса.  Для  большинства
примеров в данной книге стек объемом в 32 слова является достаточным.
     Команды PUSH, PUSHF, CALL, INT, и INTO заносят в стек адрес  возврата
или содержимое флагового регистра. Команды POP, POPF, RET и IRET извлекают
эти aдреса или флаги из стека.
     При передаче  управления  в  EXE-программу  система  устанавливает  в
регистрах следующие значения:

     DS и ES:  Адрес  префикса  программного  сегмента  -  область  в  256
(шест.100)  байт,  которая предшествует выполняемому программному модулю в
памяти.

     CS: Адрес точки входа в программу (адрес первой выполняемой команды).

     IP: Нуль.

     SS: Адрес сегмента стека.

     SP: Относительный адрес, указывающий на вершину стека.  Например, для
Предыдущая страница Следующая страница
1 ... 12 13 14 15 16 17 18  19 20 21 22 23 24 25 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама