Assembler для начинающих


Команды сравнения



Команды сравнения


      Как и в наборе команд микропроцессора 8088, у сопроцессора 8087
    есть команды, сравнивающие два числа.  Сопроцессор 8087 отбрасывает
    результат сравнения, но устанавливает в соответствии с ним флаги
    состояния.    Перед тем как опросить флаги состояния, программа
    должна считать слово состояния в память.  Далее проще всего
    загрузить флаги состояния в регистр AH, а затем, для легкости
    проверки условия, - в регистр флагов макропроцессора 8088.
 
      На Фиг. 7.18 показан листинг ассемблера команд сравнения
    сопроцессора 8087.  Так как в операции всегда участвует вершина
    стека, в программе надо указать только один регистр или операнд в
    памяти.  После сравнения в слове состояния содержится информация о


    соотношении двух чисел.  Таблица на Фиг. 7.19 показывает возможные
    варианты соотношений.  Для отражения результата сравнения
    необходимы только два бита состояния - C3 и C0; расположение C3 и
    C0 в слове состояния показано на Фиг. 7.8.
      На Фиг. 7.20 приведен фрагмент программы, которая сравнивает
    содержимое вершины стека и слово в памяти.  Переходы в этой
    программе выполняются на основе результата сравнения.  В одном из
    четырех случаев числа нельзя сравнить.  Это происходит тогда, когда
    одно из чисел есть NAN (не число) или одна из форм бесконечности.
            Microsoft (R) Macro Assembler Version 5.00                1/1/80 04:04:18
            Фиг. 7.18 Команды сравнения сопроцессора 8087             Page     1-1
 
                                          PAGE  ,132
                                          TITLE Фиг. 7.18 Команды сравнения сопроцессора 8087
 
             0000                   CODE  SEGMENT
                                          ASSUME      CS:CODE,DS:CODE
 
             0000                   WORD_INTEGER      LABEL WORD
             0000                   SHORT_INTEGER     LABEL DWORD
             0000                   SHORT_REAL  LABEL DWORD
             0000                   LONG_REAL   LABEL QWORD
 
             0000  9B D8 D1               FCOM
             0003  9B D8 D2               FCOM  ST(2)
             0006  9B DE 16 0000 R              FICOM WORD_INTEGER
             000B  9B D8 16 0000 R              FCOM  SHORT_REAL
             0010  9B D8 D9               FCOMP
             0013  9B DA 1E 0000 R              FICOMP      SHORT_INTEGER
             0018  9B DC 1E 0000 R              FCOMP LONG_REAL
             001D  9B DE D9               FCOMPP
             0020  9B D9 E4               FTST
             0023  9B D9 E5               FXAM
 
 
             0026                   CODE  ENDS
                                          END
 
            Фиг. 7.18 Команды сравнения сопроцессора 8087
 
    Сопроцессор 8087 помещает флаги состояния C3 и C0 в точности на те
    же места, которые в регистре флагов микропроцессора 8088 занимают
    флаги нуля C3 и переноса C0.  Как показано на рисунке, если
    программа переслала старший байт слова состояния сопроцессора 8087
    в регистр флагов микропроцессора 8088, она может выполнить условный
    переход с помощью непосредственной проверки состояния флагов с
    использованием команды условного перехода, и не нужно выделять и
    проверять отдельные биты слова состояния.
 
      С3    С0          Порядок
     --------------------------------------------------------------
      0     0     ST > источник
      0     1     ST < источник
      1     0     ST = источник
      1     1     ST и источник несравнимы
     --------------------------------------------------------------
 
      Фиг. 7.19 Порядок сравнения
 
      На Фиг. 7.18 демонстрируется, что существуют и другие варианты
    команды FCOM, в том числе и то, что для команды FCOM существует
    версия FICOM необходимая для ставнения целых чисел.  Команды FCOMP
    и FICOMP идентичны командам FCOM и FICOM, за исключением того, что
    сопроцессор 8087 извлекает из стека содержимое вершины после
    выполнения операции.  Это позволяет сравнить два числа с помощью
    сопроцессора 8087, не беспокоясь о том, что нужно удалить из стека
    первый операнд после операции.
 

            Microsoft (R) Macro Assembler Version 5.00              1/1/80 04:04:23
            Фиг. 7.20 Условный переход                        Page         1-1
 
 
                                          PAGE    ,132
                                          TITLE   Фиг. 7.20 Условный переход
 
             0000                   CODE    SEGMENT
                                          ASSUME  CS:CODE,DS:CODE
 
             0000                   WORD_INTEGER    LABEL   WORD
             0000  ????             STATUS_WORD     DW      ?
 
                                    ;-----  Сравнивается WORD_PTR со словом на вершине стека сопроцессора 8087
 
             0002  9B DE 16 0000 R              FICOM   WORD_INTEGER    ; Сравнение слова с ST
             0007  9B DD 3E 0000 R              FSTSW   STATUS_WORD     ; Сохранение слова состояния 8087
             000C  9B                     FWAIT             ; Синхронизация процессора с сопроцессором
             000D  8A 26 0001 R                 MOV     AH,BYTE PTR STATUS_WORD+1
             0011  9E                     SAHF              ; Занесение флагов (C0=CF,C3=ZF)
             0012  72 02                        JB      CONTINUE        ; Проверка флага C0,переход если 0
             0014  75 00                        JNE     ST_GREATER      ; Проверка флага C3
             0016                   ST_EQUAL:               ; Попадаем сюда,если C3=1,C0=0 -
                                    ; ...                   ;  значения равны
             0016                   ST_GREATER:             ; Попадаем сюда,если C3=0,C0=0 - число
                                    ; ...                   ;  на вершине стека 8087 больше WORD_PTR
             0016                   CONTINUE:
             0016  75 00                        JNE     ST_LESS         ; Проверка флага C3
             0018                   UNORDERED:              ; Попадаем сюда,если C3=1,C0=1 - невоз-
                                    ; ...                   ;  можно определить какое из чисел больше
             0018                   ST_LESS:                      ; Попадаем сюда,если C3=0,C0=1 - число
                                    ; ...                   ;  на вершине стека 8087 меньше WORD_PTR
 
             0018                   CODE    ENDS
                                          END
 
            Фиг. 7.20 Условный переход
 
      У команды FCOMPP программист не указывает никаких операндов.
    Эта команда всегда сравнивает верхние два элемента стека.  После
    сравнения они оба исчезают из стека.
 
      Команды сравнения с извлечением из стека обеспечивают удобный
    способ очистки стека.  Поскольку у сопроцессора 8087 нет команды,
    удобно извлекающей операнд из стека, вместо нее можно использовать
    команды сравнения с извлечением из стека.  Эти команды также
    изменяют и регистр состояния, и их нельзя использовать, если биты
    состояния имеют значение для дальнейшей работы, но в большинстве
    случаев эти команды позволяют быстро извлечь из стека один или два
    операнда.  Так как сопроцессор 8087 регистрирует ошибку при
    переполнении стека, необходимо удалить все операнды из стека при
    окончании вычислений.
 
      Существуют две специальные команды сравнения.  Команда
    сравнения содержимого вершины стека с нулем FTST, с помощью которой
    можно быстро определить знак содержимого вершины стека.  (Результат
    сравнения иллюстрируется таблицей на Фиг. 7.19, нужно только всюду в
    таблице слово "источник" заменить на слово "нуль").
 
      Команда FXAM, строго говоря, не является командой сравнения.
    Хотя она и работает с содержимым вершины стека, но не сравнивает
    содержимое вершины ни с одним другим числом.  Скорее команда FXAM
    устанавливает все четыре флага регистра состояния (от C3 до C0
    включительно), показывая, какого типа число находится в вершине
    стека.  Так как сопроцессор 8087 может обрабатывать любые формы
    чисел, а не только нормализованные числа с плавающей точкой,
    команда FXAM определит, что же находится в вершине стека.  На
    Фиг. 7.21 показаны значения битов состояния в каждом случае.
 
      Если при арифметической обработке вы не делаете что=либо из
    ряда вон выходящее и не работаете на пределе разрядной сетки
    сопроцессора 8087, то не нужно рассматривать никакие из приведенных
    выше результатов команды FXAM; вы должны ожидать увидеть лишь
    положительные либо отрицательные нормализованные числа или нули.
    Если выясняется, что вершина стека пустая, то обычно выдается
    ошибка.  Программа может сделать такую проверку для контроля
    параметра, переданного в вершине стека.
 
      Остальные значения - это реакция микросхемы 8087 на ошибку.
    Когда сопроцессор 8087 обнаруживает ошибку, он пытается возбудить
    прерывание по особой ситуации, устанавливая соответствующие биты в
    слове состояния.  Однако если ситуация замаскирована с помощью
    управляющего слова, сопроцессор 8087 сам реагирует на нее.    Он
    решает, какая реакция соответствует данной ошибке и возбуждает
    появление специфического числа в регистре.  Например, результат NAN
    возникает, если операция некорректна, как в случае извлечения
    квадратного корня из отрицательного числа.  Бесконечность
    появляется, если результат операции слишком велик для представления
    с плавающей точкой.

      C3    C2    C1    C0    Значение          С3    С2    С1    С0    Значение
      ---------------------------------------------------------------------------------------------------
       0    0    0     0     + Ненормально           1    0     0     0     + 0
       0    0    0     1     + NAN             1    0     0     1     Пусто
       0    0    1     0     - Ненормально           1    0     1     0     - 0
       0    0    1     1     - NAN             1    0     1     1     Пусто
       0    1    0     0     + Нормально       1    1     0     0     + Ненормальное
       0    1    0     1     + Бесконечность    1    1     0     1     Пусто
       0    1    1     0     - Нормально       1    1     1     0     - Ненормальное
       0    1    1     1     - Бесконечность    1    1     1     1     Пусто
      ---------------------------------------------------------------------------------------------------

                Фиг. 7.21 Пример интерпретации кодов состояний
Денормализованные и ненормализованные числа возникают при
    достижении другого предела представления чисел с плавающей точкой.
    Когда число становится настолько маленьким, что у него уже нет
    смещенного порядка, оно становится денормализованным.  Вместо того,
    чтобы заменить число нулем, процессор 8087 записывает наименьшее
    значение порядка и ненормализованную мантиссу.  Это означает, что
    число теряет точность, так как у его мантиссы появляются незначащие
    нули.  Но денормализованный результат все же точнее, чем просто
    нуль.  И это тот случай, при котором сопроцессор 8087, продолжая
    работу, наилучшим образом реагирует на плохие условия.  Пометка
    числа, как денормализованного, должна насторожить вас.  При этом
    также устанавливается бит денормализации в регистре особых
    ситуаций, и остается установленным до тех пор, пока команда FCLEX
    не сбросит биты особых ситуаций.  С помощью анализа флагов
    программа может зарегистрировать возникновение ошибки и отнестись к
    результатам с подозрением.




Содержание раздела