ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



Глава 10. ПРОГРАММИРОВАНИЕ РАСШИРЕНИЯ ЧИСЛОВОЙ ОБРАБОТКИ ФИРМЫ INTEL
             NPX с точки зрения программиста
             Использование средств MS-DOS с NPX
             Примеры программирования NPX с помощью MASM
             Краткое содержание


             Мир MS-DOS принадлежит исключительно Intel.  Это дает пользо-
         вателям MS-DOS два преимущества. Во-первых, программы, написанные
         для MS-DOS, переносимы даже на уровне объектных кодов. Во-вторых,
         большинство систем MS-DOS могут использовать чипы расширения чис-
         ловой обработки 8087,  80287 или 80387 фирмы Intel.  Во всей этой
         главе  мы  будем ссылаться на расширение числовой обработки с по-
         мощью аббревиатуры NPX.  Задачей NPX является обеспечение семейс-
         тва процессоров 8086, систем 80286 и 80386 способностью выполнять
         быстрые вычисления с плавающей запятой.
             NPX обеспечивает  систему командами для выполнения преобразо-
         ваний чисел,  основных математических действий, а также некоторых
         трансцендентных функций, таких как синус, косинус и логарифм.
             Возможности NPX не ограничиваются  только  скоростью  работы.
         Посредством того,   что составляет библиотеку математических под-
         программ с  плавающей  запятой,  NPX избавляет программиста от их
         написания, повышая таким образом скорость программирования. Кроме
         того,  так как эти подпрограммы содержатся в чипе NPX, а не в па-
         мяти программы,  использование NPX может  привести  к  уменьшению
         размера программы, что снижает стоимость некоторых разработок.
             В отличие  от  ранних  математических процессоров,  таких как
         Intel 8231 и 8232, доступ к NPX осуществляется посредством управ-
         ляющих последовательностей,  которые могут показаться программис-
         ту, работающему на языке ассемблера, командами на машинном языке.
         NPX не требует установки какого-либо дополнительного программного
         обеспечения (также как 8088 или главный чип центрального  процес-
         сора  конфигурирован  в "максимальном режиме"),  и не требует для
         доступа программного ввода/ вывода или передачи DMA.
             Ввиду того, что NPX полностью совместим с предлагаемыми стан-
         дартами IEEE (Институт инженеров по электротехнике и радиолектро-
         нике)  для  вычислений  с плавающей запятой,  доступна обширная и
         расширяющаяся база передового программного обеспечения для число-
         вых  вычислений.  Эта  база соответствует способу обработки чисел
         NPX. Для программиста, у которого нет времени для написания слож-
         ных  числовых подпрограмм,  это программное обеспечение сохраняет
         время и деньги.
             Применение 8087 NPX с процессорами 8086 и 8088 не ограничено.
         8087 NPX также может быть использовано  с  процессорами  80186  и
         80188.  Для пользователей процессора 80286 фирма Intel предостав-
         ляет 80287 NPX.  А пользователям  процессора  80386  предлагается
         80387 NPX.  Обратите внимание,  что некоторые системы, основанные
         на 80386, имеют гнездо для подключения 80287 NPX в дополнение или
         вместо  гнезда для 80387,  так как 80287 был дешевле и доступнее,
         чем 80387 NPX в то время, когда процессор 80386 был только объяв-
         лен. Несмотря  на это, информация, представленная в данной главе,
         имеет силу для всех этих комбинаций.

                                      - 10-2 -

                          NPX с точки зрения программиста

             В последующих разделах обсуждаются аспекты NPX, о которых не-
         обходимо помнить при написании программ для NPX.  Они включают  в
         себя  регистры данных,  форматы данных с плавающей запятой и дру-
         гие, набор команд NPX, режимы адресации, а также слова управления
         и состояния.

                               Регистры данных в NPX

             Несмотря на то, что команды NPX появляются как часть основно-
         го набора команд процессора,  NPX не имеет доступа к основным ре-
         гистрам центрального процессора.  Вместо этого NPX обладает своим
         собственным набором регистров и связывается с центральным процес-
         сором посредством общей памяти. Это не является ограничением вви-
         ду того,  что основные  регистры  центрального  процессора  плохо
         приспособлены для работы с вещественными числами. Вместо 16-бито-
         вых или 32-битовых регистров,  используемых центральным процессо-
         ром, NPX имеет восемь 80-битовых регистров и поэтому может содер-
         жать значительно больше  информации.  Эти  регистры  показаны  на
         рисунке 10-1.
          Слово     Регистры
         признака    данных
          ЪДДї    ЪДДДДДДДДДДї    ЪДДДДДДДДДДДДДДДДДДї
          і 0і    і   ST(0)  і    іCлово состояния   і
          ГДДґ    ГДДДДДДДДДДґ    АДДДДДДДДДДДДДДДДДДЩДоступны посредством
          і 1і    і   ST(1)  і                        операндов NPX
          ГДДґ    ГДДДДДДДДДДґ    ЪДДДДДДДДДДДДДДДДДДї
          і 2і    і   ST(2)  і    іCлово управления  і
          ГДДґ    ГДДДДДДДДДДґ    АДДДДДДДДДДДДДДДДДДЩ
          і 3і    і   ST(3)  і
          ГДДґ    ГДДДДДДДДДДґ
          і 4і    і   ST(4)  і                        Доступно только
          ГДДґ    ГДДДДДДДДДДґ    ЪДДДДДДДДДДДДДДДДДДїпосредством FSAVE
          і 5і    і   ST(5)  і    іУказатель команды іДї    и FSTENV
          ГДДґ    ГДДДДДДДДДДґ    АДДДДДДДДДДДДДДДДДДЩ і
          і 6і    і ST(6)    і                         іУказатели главной
          ГДДґ    ГДДДДДДДДДДґ    ЪДДДДДДДДДДДДДДДДДДї іобщей памяти CPU
          і 7і    і   ST(7)  і    іУказатель операндаіДЩ
          АДДЩ    АДДДДДДДДДДЩ    АДДДДДДДДДДДДДДДДДДЩ

                       Рис.10-1. Размещение регистров в NPX

             Вы должны помнить,  что в отличие от центрального процессора,
         регистры данных NPX не имеют уникальных имен, но они являются ин-
         дексированными элементами стека (например,  ST(1)).  Значения за-
         гружаются в NPX посредством помещения их в стек, а некоторые зна-
         чения (но не все)  восстанавливаются  путем  выталкивания  их  из
         стека.  Многие  команды  NPX работают только на вершине стека,  а
         большинство других команд установлены по умолчанию для  работы на
         вершине стека.
             То, что NPX обращается к своим регистрам как к  стеку,  очень
         важно, ввиду того, что все адреса регистров относительны к верши-
         не стека!  Например, значение, содержащееся в регистре i хранится
         в  регистре i-1,  если стек вытолкнут,  и в регистре i+1,  если в
         стек помещается новое значение.

                                      - 10-3 -
             При написании программ для NPX,  уделяйте особое внимание по-
         ведению стека. Вы не можете вставить значение в регистр и предпо-
         ложить,  что  позже  это значение будет находиться в том же самом
         месте.


             Представление в NPX вещественных чисел с плавающей точкой

             Эти регистры  также отличаются от регистров центрального про-
         цессора тем,  что они могут содержать только один тип числа,  ве-
         щественное  число  с  плавающей точкой (называемое на языке Intel
         временным вещественным). Самый верхний формат на рисунке 10-2 по-
         казывает, как в регистре NPX выглядит вещественное число с плава-
         ющей точкой.  Из рисунка видно, что регистр разделен на три поля:
         бит знака,  смещенный порядок (15 бит) и значащая часть числа (64
         бита).  Каждое из этих чисел, взятое отдельно, представляет собой
         двоичное целое без знака,  но   соединенные вместе,  они выражают
         очень большое число!
             Давайте посмотрим  внимательнее на отдельные части веществен-
         ного числа с плавающей точкой. Самая левая часть (бит 79) являет-
         ся битом знака.  Когда он имеет значение 1,  то число отрицатель-
         ное.  Когда он имеет значение 0,  то число положительное. Просто,
         но надо отметить два момента.  Во-первых,  в отличие от двоичного
         дополнения целых чисел (используемых в главном  центральном  про-
         цессоре), это вещественное число с плавающей запятой имеет столь-
         ко положительных чисел, сколько и отрицательных. (Вы увидите  это
         позже).  Во-вторых,  более важно то, что данная система счисления
         имеет два типа нуля! Это означает, что 0 может быть положительным
         или  отрицательным  числом,  и что 0 не обязательно равен 0.  NPX
         следит за этим эффектом,  но об этом надо помнить, если Вы пытае-
         тесь сравнить вещественные числа с помощью центрального процессо-
         ра.(Вам это может никогда не понадобиться, так как NPX сравнивает
         числа очень хорошо).
             Перейдя к правой стороне числа,  мы увидим мантиссу (биты с 0
         по 63).  Здесь представлены значащие цифры числа.  Так как каждый
         элемент может быть либо положительным, либо отрицательным, диапа-
         зон для каждого один и тот же. Обратите внимание, что бит 63 (са-
         мый значимый бит мантиссы) показан как 1.  Это  происходит  из-за
         того,  что NPX обычно хранит числа в нормализованном формате, ко-
         торый означает,  что NPX находит самую левую 1 в двоичном числе и
         сдвигает вверх или вниз до тех пор, пока 1 не окажется в бите 63.
         (Число без 1 означает 0, и его представлением являются все нули.)
         Приведем небольшой пример с числом 10:

         Десятичное:                                                 10
         Шестнадцатиричное:                                           A
         Двоичное 64-битовое целое:   000000000000000...000000000001010
         64-битовое вещественное NPX: 101000000000000...000000000000000

             Видите, как скользит влево число в NPX? Это дает больше места
         для других представляемых чисел,  таких как 10.1, 10.12 и так да-
         лее.  Единственной проблемой является то,  что число в NPX больше
         не 10.  Оно выглядит теперь как 10 х 2 .  Как NPX узнает, что это
         число действительно 10?  Оно использует то,  что называется полем
         экспоненты (биты с 64 по 78).
             NPX всегда предполагает,  что число в мантиссе  располагается
         между 1 и 2.  Само по себе число, показанное выше, будет двоичным

                                      - 10-4 -
         1.01 или десятичным 1.25.  (Каждая двоичная цифра в дробной части
         представляет собой 1/2 предыдущей двоичной цифры,  поэтому, пози-
         циями вправо десятичной точки в двоичном исчислении являются 1/2,
         1/4,  1/8,  1/16,  и  т.д.)  NPX  запоминает в поле экспоненты на
         сколько позиций сдвинуто первоначальное число. В случае числа 10,
         NPX сдвигает десятичную точку на три позиции от 1010.0 (двоичное)
         к 1.0100 (двоичное).  Значение 3 хранится в поле экспоненты. Есть
         еще одна хитрость в хранении данных NPX.  Так как экспонента хра-
         нится как целое без знака,  и если NPX помещает точную экспоненту
         в поле, то невозможно будет сохранить числа, меньше 1 (отсутствие
         отрицательной экспоненты означает невозможность чисел меньше, чем
         2 или единица).  Таким образом,  NPX смещает (добавляет смещение)
         экспоненту.  В NPX используется смещение 3FFFh, или 16,383 (деся-
         тичное). В примере сохранения числа 10, смещение экспоненты опре-
         деляется как 3 плюс 3FFFh, или 4002h.

                           ЪДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
         Вещественное с    і  іСмещенный по-і       Мантисса             і
         плавающей запятой іЗнірядок 3FFFh  і1                           і
                           АДДБДДДДДДДДДДДДДБДБДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                           79             64 63                          0
                                             АДДД1.0 задана явно
                           ЪДДВДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
           Упакованное     і  іНе использу-і  Упакованные десятичные     і
           десятичное      іЗні   ется     і17 16 15   цифры   3  2  1  0і
                           АДДБДДДДДДДДДДДДБДДБДДБДДБДДБДДБДДБДДБДДБДДБДДЩ
                           79            72 71                           0

                                        ЪДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДї
                         Длинное        і  іСмещенный по-і Мантисса      і
                         вещественное   іЗнірядок 3FFFh  і               і
                                        АДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДДЩ
                                        63              52АД1.0
                                                           подразумевается
                                        ЪДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
                         Длинное        і  іПредставление целого в допол-і
                         целое          іЗні      нительном коде         і
                                        АДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                                        63                               0

                                                 ЪДДВДДДДДДДВДДДДДДДДДДДДї
                                   Короткое      і  іПорядокі  Мантисса  і
                                   вещественное  іЗні  7Fh  і            і
                                                 АДДБДДДДДДДБДДДДДДДДДДДДЩ
                                                 31        23АД1.0       0
                                                           подразумевается
                                                 ЪДДВДДДДДДДДДДДДДДДДДДДДї
                                      Короткое   і  і   Дополнительный   і
                                      целое      іЗні       код          і
                                                 АДДБДДДДДДДДДДДДДДДДДДДДЩ
                                                 31                      0
                                                           ЪДДВДДДДДДДДДДї
                                               Целое-      і  іДополните-і
                                               -слово      іЗнільный код і
                                                           АДДБДДДДДДДДДДЩ
                                                           15            0
                        Рис.10-2. Представление чисел в NPX

                                      - 10-5 -

             Мы все сделали,  теперь посмотрим на рисунок 10-3, чтобы уви-
         деть,  как число 10 выглядит внутри NPX. Почему Вы должны понять,
         как NPX  хранит  числа?  Потому что иногда в процессе отладки Вам
         требуется проверить содержимое регистров NPX и, в целях понимания
         использования  и  ограничений  некоторых более продвинутых команд
         NPX, необходимо знать типы данных, которыми Вы манипулируете.

            79 78 ... 64 63 62    ............     0
           ЪДВДДДДДДВДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДї
           і0і 40 02і 1і  010    000    000    000 і
           АДБДДДДДДБДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                    

            +   2(3) x1.010=1010(Binary)=10(Decimal)


                      Рис.10-3. Представление числа 10 в NPX


                     Другие форматы данных, используемые в NPX

             На рисунке 10-2 кроме 80-битового формата вещественного числа
         с плавающей запятой показаны шесть других  форматов  данных.  Для
         чего они применяются?  Вместе с 80-битовым вещественным NPX может
         использовать эти формы для чтения и записи  вещественных  данных.
         Если  эти  данные  представлены в одном из этих форматов,  то NPX
         поймет их.  Другие форматы NPX не воспринимает. Три основных типа
         показаны на рисунке 10-2.  Эти типы включают в себя вещественное,
         целое и упакованное десятичное.


                   Короткий вещественный и длинный вещественный
                                  форматы данных

             Короткий вещественный (32-битовый) и длинный вещественный (64
         -битовый)  форматы очень похожи на 80-битовый вещественный с пла-
         вающей запятой,  который мы уже рассмотрели.  Эти числа  способны
         представлять вещественные числа с плавающей запятой, но с меньшим
         диапазоном и точностью. Различия показаны в таблице 10-1.
                                                         Таблица 10-1
                   Различия между форматами вещественных данных
         ДДДДДДДДДДДДВДДДДДДДДВДДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДД
         Тип данных  іМантиссаі Экспонентаі Смещение    іСамая левая
                     і # бит  і   # бит   і экспоненты  іединица
         ДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДД
                     і        і           і             і
         80-битовый  і        і           і             і
         вещественныйі  64    і   15      і 3FFF(16383) іОпределена
         64-битовый  і        і           і             і
         вещественныйі  52    і   11      і 3FF(1023)   іПредполагается
         32-битовый  і        і           і             і
         вещественныйі  23    і    8      і 7F(127)     іПредполагается
         ДДДДДДДДДДДДБДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДДД

             Кроме размера короткий и длинный вещественные форматы отлича-
         ются от 80-битового вещественного тем, что самый значимый бит ре-

                                     - 10-6 -
         ально не появляется!  Из-за своего ограниченного пространства эти
         форматы всегда предполагают 1 в самой левой позиции, но не хранят
         1, таким образом они приобретают позицию для другой цифры.


                    Целое слово, короткий целый и длинный целый
                                  форматы данных

             Формы целого хорошо известны.  Эти формы  используются  цент-
         ральным  процессором для хранения дополнения двоичных целых чисел
         (хотя центральный процессор не может применять  формат 8-битового
         длинного целого). Эти числа имеют следующие диапазоны:
             64-битовый:
             от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807
             32-битовый:
             от -2,147,483,648 до 2,147,483,647
             16-битовый:
             от -32,768 до 32,767

             Эти числа  отличаются  от  вещественных чисел тем,  что любое
         значение,  загруженное из этой формы, является точным представле-
         нием числа.  Помните также, что хотя эти числа имеют знак и самый
         значимый бит отражает знак числа,  они все же  выражают  двоичные
         дополнения чисел.


                Форматы упакованного двоично-десятичного кода (BCD)

             Последней формой представления данных в NPX  является  упако-
         ванный BCD (двоично-десятичный код). Что такое упакованный BCD? В
         системе счисления двоично-десятичного кода каждый 4-битовый полу-
         байт представляет собой отдельную цифру, которая может иметь зна-
         чение между 0 и 9.  Все число представляет  собой  только  строку
         цифр.  Таким  образом,  число  больше  похоже  на строку символов
         ASCII.  На рисунке 10-4 показано представление числа 256  в  нор-
         мальной двоичной форме и форме двоично-десятичного кода.  Неболь-
         шие вычисления проводятся в десятичной системе счисления.

                  ЪДДВДДДДДДВДДДДДї             ЪДДВДДДДДДВДДДДДї
                  і01і 0000 і 0000і             і01і 0000 і 0000і
                  АДДБДДДДДДБДДДДДЩ             АДДБДДДДДДБДДДДДЩ
                  9-8  7...4 3...0              9-8  7...4 3...0
                                                        
                   1     0     0                 2      5    6

         Двоичный:1x256 + 0x16 + 0x1 = 256     2x256 + 5x16 + 6x1 = 598
         Двоично-
         десятич.:1x100 + 0x10 + 0x1 = 100     2x100 + 5x10 + 6x1 = 256

              Рис.10-4. Представление числа в двоично-десятичном коде

             Из рисунка 10-4 видно,  что мы пишем числа в двоично-десятич-
         ном коде,  как если бы они были шестнадцатиричными (одна цифра на
         каждый 4-битовый полубайт),  но интерпретируем их как десятичные.
         Но почему эта форма данных так важна?  Потому, что она служит для
         преобразований  между  ASCII и упакованным BCD.  Рисунок 10-5 де-
         монстрирует,  что для перехода из BCD в ASCII  Вы  должны  только

                                      - 10-7 -
         распаковать цифры (одну на полубайт) в байты и прибавить шестнад-
         цатиричное 30 для формирования символов ASCII от 0 до 9 (шестнад-
         цатиричные с 30 по 39).  Для выполнения обратного  преобразования
         надо вычесть 30h из каждого символа и упаковать  их,  по  два  на
         байт.

                               ЪДДВДДДДДДВДДДДДї
                               і01і 0000 і 0000і
                               АДДБДДДДДДБДДДДДЩ
                               9-8  7...4 3...0
            Двоично-десятичный            
                 формат         2     5     6
                                і     і     і
                                і     і     і
                     ЪДДДДДДДДДДЩ     і     АДДДДДДДДДДї
                     і                і                і
                                                     
            ЪДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДї
            і 0011      0010 і 0011      0101  і 0011      0110  і
            АДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДЩ
                  7.......0       7........0        7........0
                      і               і                  і
                                                       
                   32(Hex)         35(Hex)            36(Hex)
                      і               і                  і
                      АДДДДДДДї       і        ЪДДДДДДДДДЩ
            Формат ASCII                     


                Рис.10-5. Преобразования между числами ASCII и BCD

             Эта форма данных применяется NPX только для загрузки и хране-
         ния чисел. Ни одна из арифметических команд не может использовать
         форму  упакованного BCD.  Даже с учетом этого ограничения команды
         загрузки и хранения упакованного BCD являются двумя наиболее  по-
         лезными командами NPX. Это происходит ввиду того, что способность
         вычислять ничего не стоит без возможности передать результаты вы-
         числений  пользователю,  а большинство людей применяют для записи
         чисел с плавающей запятой десятичную систему счисления.
             NPX обеспечивает  возможность преобразования десятичных чисел
         в двоичные и обратно. Программист должен только следить за преоб-
         разованиями  между  строками ASCII и упакованным BCD,  а также за
         правильным расположением десятичной точки (мы  рассмотрим  это  в
         разделе,  посвященном  преобразованию между десятичными числами и
         двоичными числами с плавающей запятой).  NPX следит за  всем  ос-
         тальным.


                              Коротко о типах данных

             В таблице 10-2 мы рассмотрели  размер  чисел,  которые  могут
         быть  представлены  каждым  типом данных вместе с приблизительным
         десятичным разрешением (количество значащих цифр), поддерживающим
         каждый  тип данных.  Для реального использования мы можем пореко-
         мендовать следующее: Использовать упакованный BCD для перехода от
         чисел  ASCII к вещественным числам с плавающей запятой и обратно.
         Использовать вещественные числа с плавающей запятой для всех  вы-

                                      - 10-8 -
         числений  и  для представления в MASM констант вещественных чисел
         (мы рассмотрим это позже). А также использовать форму минимально-
         го целого, пригодную для числа, выражающего константу целого чис-
         ла в MASM.  Следуя этим указаниям мы  можем  получить  наибольшую
         точность  с  некоторым сохранением объема памяти путем применения
         где возможно формы меньшего целого.
             Рисунок 10-6  демонстрирует  диапазон  представления  числа в
         NPX.  Обратите внимание, что NPX хранит числа с большей точностью
         внутри  (80-битовое вещественное),  чем при загрузке и сохранении
         регистров NPX (длинное вещественное). Это дает дополнительный за-
         пас точности для вычислений. Отметьте также, что пробел между от-
                                                         Таблица 10-2
                       Диапазон и точность типов данных NPX
         ДДДДДДДДДДДДВДДДДДДДДДВДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         Тип данных  і ДвоичныеіДесятичныеі Приблизительный диапазон
                     і биты    іцифры     і
         ДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         Вещественноеі         і          і
         с плавающей і         і          і
         запятой     і  80     і  19      і 3.4х10     < N < 1.2х10
         Упакованное і         і          і
         десятичное  і  80     і  18      і -10  -1 < N < 10  -1
         Длинное     і         і          і
         вещественноеі  64     і  15-16   і 4.19х10    < N < 1.6х10
         Длинное целое  64     і  18      і -9х10  < N < +9х10
         Короткое    і         і          і
         вещественноеі  32     і   6-7    і 8.43х10   < N < 3.37х10
         Короткое    і         і          і
         целое       і  32     і   9      і -2х10 < N < +2х10
         Целое слово і  16     і   4      і -32,768 < N < +32,767
         ДДДДДДДДДДДДБДДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

          І Внешний диапазон внутреннего представления

          ° Внешний диапазон длинного вещественного


                        Основной              Основной
                        диапазон              диапазон
                       2(64) - 2           2(64) - 2
                   Уникальное значение   Уникальное значение
                        #'s                  #'s
      - беско-   -8  -4  -2  -1 -1/2  0  1/2  1   2   4   8     + беско-
        нечность          ЪДДДї               ЪДДДї             нечность
                   Exp Exp Exp Exp         Exp Exp Exp Exp
                    2   1   0   1           1   0   1   2
           ДДДДґГДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДДДДДґГДДДДД
           І°Дї                   ЪД°ІіІ°Дї                          ЪД°І
           ІДї -1.67x10(308)     і ЪІіІї і             +1.67x10(308)ЪДІ
             і          -4.19x10(-307) +4.19x10(-307)               і
             -1.2x10(4932)         і   і                  +1.2x10(4932)
                       -3.4x10(-4932)  +3.4x10(-4932)

         Плотность чисел                Плотность чисел
                      ДДДДДДДДДДДДДДД>             ДДДДДДДДДДДДДДДДДДДД>
         уменьшается к 0                увеличивается к бесконечности

                   Рис.10-6. Диапазон представления чисел в NPX

                                      - 10-9 -
         дельными представляемыми числами (расстояние между двумя смежными
         числами,  которые NPX может представить точно) уменьшается к нулю
         (в обоих направлениях) и увеличивается к бесконечности  (плюс или
         минус).  Эта плотность представления числа подразумевает, что NPX
         с большей точностью обрабатывает очень  маленькие  числа,  нежели
         большие.

                                 Набор команд NPX

             NPX имеет то,  что в индустрии называется богатым набором ко-
         манд. Это не обязательно означает, что имеется много команд (хотя
         он имеет 69 различных команд),  а то,  что  набор  команд  хорошо
         приспособлен для выполнения требуемых операций. Существуют коман-
         ды почти для каждой операции, что значительно сокращает количест-
         во шагов (и соответствующих трудностей при программировании), ко-
         торые могут встретиться при использовании менее мощного числового
         сопроцессора.
             В таблице 10-3 приведены 69 команд.  Таблица организована  по
         типам  выполняемых операций,  а не в алфавитном порядке,  так как
         предпочтительнее искать команду по типу, чем по имени. Необходимо
         пояснить два обозначения,  присутствующие в таблице 10-3. Сначала
         отметку (P), появляющуюся в некоторых командах. Это означает, что
         соответствующая  команда  может  быть  использована  в форме POP,
         FopP. Форма POP указывает NPX, что необходимо увеличить указатель
         стека  и определить регистр прежней вершины стека как пустой, что
         существенно понижает вершину стека.  Все это становится ясным да-
         лее.


                                   Префикс FWAIT

             Второе обозначение в таблице 10-3 - это отметка  (N). Отметка
         (N) означает, что соответствующая команда может быть использована
         в форме no-wait,  как в FNop.  Обычно ассемблер  MASM  генерирует
         префикс FWAIT для каждой команды NPX. Форма no-wait указывает ас-
         семблеру MASM,  что надо генерировать префикс FWAIT.  Так что  же
         такое префикс FWAIT?
             Обычно NPX должен ожидать завершения текущей  команды,  перед
         тем  как  он  примет новую.  Это достигается посредством префикса
         FWAIT  кода  операции  (9В  шестнадцатиричное),  который  реально
         представляет собой код  операции  8086!  Выполняя  эту  операцию,
         главный центральный процессор ждет, когда контакт TEST интерфейса
         центральный процессор/NPX станет активным.  Это происходит, когда
         NPX,  завершив выполнение команды,  ожидает новую.  Главный цент-
         ральный процессор вновь приступает к работе и вызывается  следую-
         щая команда NPX, начиная новый цикл.
             Причина использования FWAIT в качестве префикса заключается в
         том,  что главный центральный процессор ждет только тогда,  когда
         хочет направить NPX другую команду.  Как только новая команда по-
         сылается NPX, центральный процессор и NPX могут работать одновре-
         менно,  и,  когда центральный процессор вновь нуждается в NPX, он
         должен проверить готовность последнего.
             Есть еще  один  случай,  когда  главный центральный процессор
         нуждается в использовании команды FWAIT.  Всякий раз,  как только
         центральному процессору необходимо прочитать данные NPX, он посы-

                                      - 10-10 -
         лает соответствующую команду записи данных в память. Главный про-
         цессор должен ждать  (посредством команды FWAIT),  пока данные не
         будут доступны. В этом случае программист должен однозначно зако-
         дировать команду NPX FWAIT,  потому что MASM не знает, какое уст-
         ройство ждет завершения выполнения команды - центральный  процес-
         сор или NPX.
                                                         Таблица 10-3
                    Перечень команд Intel NPX и формы адресации
         ДДДДДДДДВДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         .       іМнемоника іСпособ     і          Имя команды
         Отметки ікоманды   іадресации  і
         ДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         .               Команды пересылки данных (9)
         -------------------------------------------------------------
         .       іFXCH      і  //d      іОбмен содержимого регистров
         .       іFLD       і  s        іЗагрузить вещественное
         (P)     іFST       і  d        іСохранить вещественное
         .       іFILD      і  s        іЗагрузить целое
         (P)     іFIST      і  d        іСохранить целое
         .       іFBLD      і  s        іЗагрузить упакованный BCD
         .       іFBSTP     і  d        іСохранить упакованный BCD
         --------------------------------------------------------------
         .                 Команды констант (7)
         --------------------------------------------------------------
         .       іFLDZ      і           іЗагрузить +0.0
         .       іFLD1      і           іЗагрузить +1.0
         .       іFLDPI     і           іЗагрузить Pi
         .       іFLDL2T    і           іЗагрузить log 10
         .       іFLDL2E    і           іЗагрузить log e
         .       іFLDLG2    і           іЗагрузить log 2
         .       іFLDLN2    і           іЗагрузить log 2
         --------------------------------------------------------------
         .            Трансцендентные команды (8)
         --------------------------------------------------------------
         .       іFPTAN     і           іОтносительный тангенс
         .       іFPATAN    і           іОтносительный арктангенс
         .       іF2XM1     і           і2  - 1
         .       іFYL2X     і           іY x log X
         .       іFYL2XP1   і           іY x log (X + 1)
         .       іFCOS      і           іКосинус ST(0) (только 80387)
         .       іFSIN      і           іСинус ST(0) (только 80387)
         .       іFSINCOS   і           іСинус и косинус ST(0)
         .       і          і           і(только 80387)
         --------------------------------------------------------------
         .                 Команды сравнения (10)
         --------------------------------------------------------------
         (P)     іFCOM      і  //s      іСравнить вещественные
         (P)     іFICOM     і  s        іСравнить целые
         .       іFCOMPP    і           іСравнить и выполнить POP дважды
         .       іFTST      і           іПроверить вершину стека
         .       іFXAM      і           іПросмотреть вершину стека
         .       іFUCOM     і           іСравнить вне порядка
         .       і          і           і(только 80387)
         .       іFUCOMP    і           іСравнить вне порядка и
         .       і          і           івыполнить POP (только 80387)
         .       іFUCOMPP   і           іСравнить вне порядка и

                                      - 10-11 -
         .                               выполнить POP дважды
         .       і          і           і(только 80387)
         --------------------------------------------------------------
         .                Арифметические команды (26)
         --------------------------------------------------------------
         (P)     іFADD      і  *        іСложить вещественные
         .       іFIADD     і  s        іСложить целые
         (P)     іFSUB      і  *        іВычесть вещественное
         .       іFISUB     і  s        іВычесть целое
         (P)     іFSUBR     і  *        іВычесть вещественное (обратное)
         .       іFISUBR    і  s        іВычесть целое (обратное)
         (P)     іFMUL      і  *        іНесколько вещественных
         .       іFIMUL     і  s        іНесколько целых
         (P)     іFDIV      і  *        іРазделить вещественное
         .       іFIDIV     і  s        іРазделить целое
         (P)     іFDIVR     і  *        іРазделить вещественное
         .       і          і           і(обратное)
         .       іFIDIVR    і  s        іРазделить целое (обратное)
         .       іFSQRT     і           іКвадратный корень
         .       іFSCALE    і           іМасштаб
         .       іFPREM     і           іЧастичный остаток
         .       іFPREM1    і           іЧастичный остаток
         .       і          і           і(IEEE, только 80387)
         .       іFRNDINT   і           іОкруглить до целого
         .       іFXTRACT   і           іВыделить экспоненту и мантиссу
         .       іFABS      і           іАбсолютное значение
         .       іFCHS      і           іСменить знак
         --------------------------------------------------------------
         .          Команды управления обработкой (16)
         --------------------------------------------------------------
         (N)     іFINIT     і           іИнициализировать процессор
         .       іFLDCW     і  s        іЗагрузить управляющее слово
         (N)     іFSTCW     і  d        іСохранить управляющее слово
         (N)     іFSTSW     і  d        іСохранить слово состояния
         #(N)    іFSTENV    і  d        іСохранить среду
         .       іFLDENV    і  s        іЗагрузить среду
         #(N)    іFSAVE     і  d        іСохранить состояние
         .       іFRSTOR    і  s        іВосстановить состояние
         .       іFINCSTP   і           іУвеличить SP
         .       іFDECSTP   і           іУменьшить SP
         .       іFFREE     і  d        іОсвободить регистр
         .       іFNOP      і           іНет операции
         .       іFWAIT     і           іЦентральный процессор ждет
         (N)     іFDISI     і           іЗапретить прерывания
         .       і          і           і(только 8087)
         (N)     іFENI      і           іРазрешить прерывания
         .       і          і           і(только 8087)
         (N)     іFCLEX     і           іСбросить ситуацию
         ДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
          * Формы командных операндов для FADD, FSUB, FMUL, FDIV, FDIVR
             :F       ... генерирует FP ST(1),ST
             :Fs      ... генерирует F ST,<память>
             :F d,s   ... только регистры d,s
             :FP d,s  ... только регистры d,s

             (P)  Формы F или FP
             (N)  Формы F или FN

                                      - 10-12 -
             s    Источник
             d    Адресат
             //s  Ничего или источник
             //d  Ничего или адресат
             #    Команда не является самосинхронизируемой

                               Способы адресации NPX

             Способы адресации NPX отражают архитектуру  стека процессора.
         Все  числовые  коды операций NPX,  в отличие от управляющих кодов
         операций,  используют вершину стека как,  по крайней  мере,  один
         операнд. Некоторые команды работают только с  вершиной стека, на-
         пример, FSQRT и FABS. Другие работают как с вершиной стека, так и
         со следующим регистром стека, например, FSCALE и F2XM1. Оставшие-
         ся двухоперандные команды изменяются в соответствии с типом.  Не-
         которые берут свой второй операнд из другого регистра стека. Дру-
         гие могут брать свой второй операнд из памяти.
             В таблице  10-4 продемонстрированы различные разрешенные ком-
         бинации адресации операндов и команд NPX.  Обратите внимание, что
         хотя некоторые математические команды и команды сравнения исполь-
         зуют операнд памяти в качестве источника, операнды памяти никогда
         не  могут применяться в качестве адресата кроме команд сохранения
         (FST
, FIST

 и FBSTR). Отметьте также, что операнд источника для любой целой команды (FIop) должен быть операндом памяти пото- му, что регистры NPX всегда содержат вещественные числа. Таблица 10-4 Разрешенные типы для числовых команд NPX ДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД і ВТОРЫЕ ОПЕРАНДЫ ГДДДДДДВДДДДДДДВДДДДДДДДВДДДДДДДДВДДДДДДДВДДДДДДДДДДДДД Пример і і іДвухмер-і і і Команды команды іСлово іДвойноеіное і Десять іРегистрі математ. и NPX і іслово іслово і байтов іNPX і сравнения ДДДДДДДДДЕДДДДДДЕДДДДДДДЕДДДДДДДДЕДДДДДДДДЕДДДДДДДЕДДДДДДДДДДДДД і і і і і і FLD і і і і і і исто- і і і і і і Веществен- чник і і Да і Да і FLD і Да і ное FST і і і і і і адресат і і Да і Да і FSTP і і Нет FILD і і і і і і источник і Да і Да і Да і і і Целое FIST і і і і і і адресат і Да і Да і Да і і і Нет FBLD і і і і і і источник і і і і Да і і Нет FBSTP і і і і і і адресат і і і і Да і і Нет ДДДДДДДДДБДДДДДДБДДДДДДДБДДДДДДДДБДДДДДДДДБДДДДДДДБДДДДДДДДДДДДД Некоторые сомнения возникают по поводу того, как NPX обраща- ется к своим операндам. Небольшой пример поможет развеять туман, поэтому давайте посмотрим на работу трех кодов операций NPX. FLD ; Загрузить 1-ый аргумент из памяти FLD ; Загрузить 2-ой аргумент из памяти FADD ; кодируется как FADD ST(1),ST FSTP ; сохранить результат в памяти - 10-13 - Эта операция использует FLD для считывания двух операндов па- мяти в стек регистра NPX, складывает их, применяя "классическую" форму FADD, и затем сохраняет результат с помощью FSTP. Помните, что в то время как основные арифметические команды (FADD, FSUB, FMUL и FDIV) кодируются сами по себе, MASM генерирует классичес- кую операцию снятия со стека, используя вершину стека ST, в ка- честве источника и следующий элемент стека ST(1) в качестве адре- сата. Работа четырех предыдущих команд представлена графически на рисунке 10-7. Мы разделили две части команды FADD таким образом, чтобы Вы могли лучше видеть эффекты снятия со стека. Гладя на операцию, Вы можете увидеть, что NPX концептуально завершает арифметическую ее часть - сохраняя результата в ST(1) - затем снимает со стека, перенося результат в вершину стека, ST или ST(0). Одна и та же команда ЪДДДДДДДДДДДДДДДДДДДДДДДї FADDP FADDP FSTP сохра- FLD помещает в стек: (ST(1)= выталкивает няет и вы- Mem-1 Mem-21 Mem-1 + Mem-2 Mem-2 талкивает SUM ЪДДДДДДДДДДїЪДДДДДДДДДДїЪДДДДДДДДДДїЪДДДДДДДДДДїЪДДДДДДДДДДї ST(0)і Mem-1 іі Mem-2 іі Mem-2 іі SUM ііПредыдущееі ГДДДДДДДДДДґГДДДДДДДДДДґГДДДДДДДДДДґГДДДДДДДДДДґГДДДДДДДДДДґ ST(1)іПредыдущееіі Mem-1 іі SUM ііПредыдущееіі і ГДДДДДДДДДДґГДДДДДДДДДДґГДДДДДДДДДДґГДДДДДДДДДДґГДДДДДДДДДДґ ST(2)і ііПредыдущееііПредыдущееіі іі і АДДДДДДДДДДЩАДДДДДДДДДДЩАДДДДДДДДДДЩАДДДДДДДДДДЩАДДДДДДДДДДЩ Рис.10-7. Пример работы со стеком NPX В конце нашего примера стек принимает свой первоначальный вид. Так ли это? Да, это так, если в стеке было место для допол- нительных аргументов. Однако, если в нем не было достаточно места для размещения новых данных, NPX объявляет о недопустимой ситуа- ции в работе ввиду переполнения стека. (Мы рассмотрим чрезвычай- ные ситуации в дальнейшем.) Следовательно, до того, как мы сможем выполнить даже нашу очень простую задачу, необходимо убедиться в том, что NPX может принимать данные. Для достижения этого сущест- вует два способа. Команды FINIT и FFREE Простейшим способом подготовки NPX к работе является исполь- зование команды FINIT. Это первая команда, которую нужно напра- вить NPX всякий раз как только начинает выполняться новая прог- рамма. FINIT инициализирует NPX таким образом, как если бы произошел сброс всей системы, что означает очистку всех регистров и ситуаций, а также обеспечивает свободное место для работы прог- раммиста. Другую возможность убедиться в том, что NPX освободил регист- ры, предоставляет команда FFREE. Она отмечает необходимый регистр как пустой и позволяет программисту использовать его для последу- ющих вычислений. Обратите внимание, что нет необходимости очищать регистры на вершине стека. Если нижняя часть стека, ST(7), имеет достаточно свободного места, верхние регистры при добавлении но- вого значения опустятся вниз. - 10-14 - Управление NPX Помимо восьми регистров данных NPX имеет четыре других ре- гистра, доступных программисту. Из рисунка 10-1 видно, что это слово состояния, слово управления, а также указатели операндов и команд. NPX также имеет регистр, называемый словом признака, но он используется только внутри NPX. (Слово признака отмечает ре- гистры как пустые, нулевые и не-число.) Два указателя, операнда и команды полезны только в процессе внешней обработки особой ситу- ации, которую мы рассмотрим далее. Остались слова управления и состояния. Для эффективного использования NPX нам необходимо по- нять работу этих регистров. Слово управления NPX Сначала мы рассмотрим регистр слова управления. Это 16-бито- вое слово определяет то, как NPX трактует различные ситуационные ЪДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДї і 15і 14і 13і 12і 11і 10і 9і 8і 7і 6і 5і 4і 3і 2і 1і 0і ГДДДБДДДБДДДЕДДДЕДДДБДДДЕДДДБДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДґ і і і і і і і і і і і і і і і ICі RC і PC іIEMі і PMі UMі OMі ZMі DMі IMі АДДДБДДДБДДДБДДДБДДДДДДДБДДДДДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДЩ АДДДДДДДДДДДЩ і АДДДДДДДБДДДДДДДЩ і і і і і і і і зарезервировано і і і і і і і і і і  і і і і і і і і і іНеверная УправлениеЪДДДДДЩ АДДДї і і і і і і і операция бесконечностью і і і і і і і іНенормализо- ЪДДДДДДДДДДДДДДДДДДДДДї і і і і і і і іванный опе- і0 = Сходящаяся і і і і і і і і  ранд і Ъ бесконеч.ї і і і і і і і  Деление на ноль і і і і і і і і і  Переполнение і- і і + і і і і і  Потеря значимости і АДДД 0 ДДДДЩ і і і і  Точность Маска і1 = Расходящаяся і і і іЗарезервирован разрешения і і і і і прерывания і-беск.<-- 0 -->+беск.і і і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї АДДДДДДДДДДДДДДДДДДДДДЩ і і АДДі0= Разрешить і і і і1= Запретить (замаскировано)і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Управление ЪДДДДДДДДДДДДЩ АДДДДДДДДДДДДї Управление округлением   точностью ЪДДДДДДДДДДДДДДДДДДДДДї ЪДДДДДДДДДДДДДДДДДДДДДДДДї і00=(x+1)<---0.5--->x і і ЪДДДДДДДДДДїі і01= ---> 0 ---> і і00= і 24 бита іі і10= <--- 0 <--- і і АДДДДДДДДДДЩі і11= ---> 0 <--- і і ЪДДДДДДДДДДДДДДДїі АДДДДДДДДДДДДДДДДДДДДДЩ і10= і 53 бита іі і АДДДДДДДДДДДДДДДЩі і ЪДДДДДДДДДДДДДДДДДДїі і11= і 64 бита іі і АДДДДДДДДДДДДДДДДДДЩі АДДДДДДДДДДДДДДДДДДДДДДДДЩ Рис.10-8. Слово управления и его влияние на операции NPX - 10-15 - условия и то, как он видит используемую систему счисления. На ри- сунке 10-8 продемонстрирована работа слова управления, а также различные поля и их воздействия. В основном, слово управления со- держит три поля управления и семь флагов для использования с осо- быми ситуациями. На данном этапе мы хотим использовать как можно больше встро- енных средств NPX. Часть этого означает то, что мы хотим восполь- зоваться встроенными возможностями обработки особых ситуаций NPX. Вы видите, что NPX само по себе может следить за большинством возникающих ошибок, исправлять число или возвращать специальное значение, называемое не-число. Так как обрабатывать эти прерыва- ния вручную сложно, мы предоставим NPX делать это за нас. Мы про- делаем это посредством маскировки особой ситуации, что выполняет- ся установкой масок ситуаций в слове управления. Все маски особых ситуаций вместе с главной маской разрешения прерываний содержатся в младшем байте слова управления. Установка NPX в режим использования своих внутренних обработ- чиков ошибок выполняется установкой младшего байта в BF (шестнад- цатиричное) с применением команды загрузки слова управления FLDCW. Мы просто определяем слово в памяти главного центрального процессора с помощью младшего байта, имеющего значение BF (шест- надцатиричное). Затем мы загружаем его следующим образом: . . . cw87 dw 03BFh ; значение слова управления NPX . . . FLDCW cw87 ; загрузить слово управления NPX . . . Зачем мы применили значение 3 для старшего байта слова управ- ления? Старший байт содержит три поля для определения используе- мой NPX модели числа. Эти три поля также показаны на рисунке 10-8. Сравнив диаграмму с нашим значением 3, Вы увидите, что мы выбрали 64-битовую точность, округление до ближайшего целого и сходящуюся бесконечность. Эти значения единственные, рекомендуе- мые фирмой Intel, а также единственные, которые NPX использует по умолчанию. Если Вы хотите изменить эти установки, рисунок 10-8 подскажет, какие значения можно применять. Слово состояния NPX Слово состояния NPX содержит четыре типа информации: (1) ин- дикатор занятости; (2) указатель вершины стека; (3) коды условий, отражающие результаты выполнения команд FCOM, FTST и FXAM; и (4) индикаторы особых ситуаций, сигнализирующие о возможности появле- ния ошибки. Рисунок 10-9 демонстрирует положения различных инди- каторов внутри слова состояния. - 10-16 - ЪДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДї і 15і 14і 13і 12і 11і 10і 9і 8і 7і 6і 5і 4і 3і 2і 1і 0і ГДДДЕДДДЕДДДБДДДБДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДЕДДДґ і і і і і і і і і і і і і і і і B і C3і ST і C2і C1і C0і IRі і PEі UEі OEі ZEі DEі IEі АДДДБДДДБДДДДДДДДДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДЩ і і АДДДДДДДДДДДБДДДДДДДДДДДЩ і і і і і і і і і АДДДДДДДДДДДДДДДДДДДі і і і і і і і   і і і і і і і і іНеверная Занято і  і і і і і і операция Указатель і Коды і і і і і іНенормализо- на вершину і условий і і і і і іванный опе- стека  і і і і і і ранд ЪДДДДДДДДДДДДДДДДДДДДДДДї і і і і і  і ЪДДДДДДДДДДДїі і і і і  Деление на ноль і000 ----> і Регистр 0 іі і і і  Переполнение і001 ----> і Регистр 1 іі і і  Потеря значимости і010 ----> і Регистр 2 іі і  Точность Маска і011 ----> і Регистр 3 іі іЗарезервирован разрешения і100 ----> і Регистр 4 іі і прерывания і101 ----> і Регистр 5 іі  і110 ----> і Регистр 6 іі Требование прерывания і111 ----> і Регистр 7 іі і АДДДДДДДДДДДЩі АДДДДДДДДДДДДДДДДДДДДДДДЩ Рис.10-9. Слово состояния NPX Индикатор занятости сигнализирует о том, выполняет ли в на- стоящее время NPX обработку команды. Этот индикатор не очень по- лезен для нас, так как содержимое слова состояния не может быть использовано до тех пор, пока NPX не объявит, что он завершил за- пись слова состояния. Исходя из этого, Вы знаете, что NPX свобо- ден, так как команда FWAIT выполнена. Указатель вершины стека, в битах с 11 по 13, полезен для программиста, который пишет сложные служебные программы NPX, вы- полняющие последовательные операции и сохраняющие многочисленные значения в стеке NPX. В этих случаях, для того, чтобы убедиться в том, что для следующей операции имеется достаточно места, перед обработкой программы проверьте глубину стека. Если в стеке недо- статочно места для поддержки операции, некоторые или все регистры должны быть сохранены в памяти для того, чтобы появилась возмож- ность выполнить программу без нежелательных последствий. Указатель стека инициализируется командой FINIT для того, чтобы указывать на 000(0), а каждая успешно загруженная команда уменьшает указатель стека циклически возвращая 111(7) до тех пор, пока он не достигнет 001(1). Указателем стека можно манипулиро- вать с помощью команд FINCSTP (увеличить указатель стека) и FDECSTP (уменьшить указатель стека). Тем не менее, так как эти операции не отмечают регистры как пустые, использование команд FDECSTP или FINCSTP может запретить применение индикатора вершины стека для проверки свободных регистров. Коды условий необходимы чаще всего для того, чтобы решить, какое действие предпринять в пункте принятия решения программы. Далее мы рассмотрим несколько примеров использования кодов усло- вий. Короче говоря, для проверки кодов условий, запишите слово состояния в память с помощью команды FSTSW; затем проверьте коды с помощью главного центрального процессора. При сохранении инфор- - 10-17 - мации состояния NPX для проверки центральным процессором не забы- вайте добавлять команду FWAIT после команды записи. Следующий фрагмент программы демонстрирует, как может появиться последова- тельность сравнения. . . . sw87 dw ? ; пространство для слова состояния NPX . . . FCOM ST(1) ; проверить отношение между ST и ST(1) FSTSW sw87 ; записать слово состояния NPX FWAIT ; ждать завершения работы test sw87,4000h ; операнды равны? je are_equl ; да... . . . Значения, присвоенные этим кодам различными командами сравне- ния, приведены в таблице 10-5. Обратите внимание, что коды усло- вий не попадают в одну группу, но делятся на части указателем стека, и что коды, возвращаемые командами FCOM и FTSR, также раз- деляются битом условия С1, который не используется. Отметьте, что NAN означает "не-число". Таблица 10-5 Условия состояния, установленные командами FCOM, FTST и FXAM ДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДД і КОДЫ УСЛОВИЙ і Команда ГДДДДДДДДДДДДДДДДДДДДДДДґ Результат і C3 C2 C1 C0 і ДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДД і і . F і 0 0 * 0 і ST > источника . C і 0 0 * 1 і ST < источника . O і 1 0 * 0 і ST = источник . M і 1 1 * 1 і ST ? источник . F і 0 0 * 0 і ST > 0.0 . T і 0 0 * 1 і ST < 0.0 . S і 1 0 * 0 і ST = 0.0 . T і 1 1 * 1 і ST ? 0.0 . F і 0 0 0 0 і + Ненормализованное . X і 0 0 0 1 і + NAN . A і 0 0 1 0 і - Ненормализованное . M і 0 0 1 1 і - NAN . і 0 1 0 0 і + Нормализованное . і 0 1 0 1 і + Бесконечность . і 0 1 1 1 і - Бесконечность . і 1 0 0 0 і + 0 . і 1 0 0 1 і Пусто . і 1 0 1 0 і - 0 . і 1 0 1 1 і Пусто . і 1 1 0 0 і + Денормализованное . і 1 1 0 1 і Пусто . і 1 1 1 0 і - Денормализованное . і 1 1 1 1 і Пусто ДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДД (*) - Не существенно - 10-18 - Обработка особых ситуаций в NPX Младший байт слова состояния содержит флаги особых ситуаций. Эти флаги соответствуют маскам ситуаций в слове управления. Когда имеет место особая ситуация, NPX устанавливает соответствующий флаг и затем проверяет, замаскирована эта ситуация или нет. Так как большинство операций применяют замаскированный ответ (внут- ренние обработчики прерываний NPX), мы свели их действие в табли- цу 10-6. Не забывайте о периодической проверке на наличие особых ситуаций в целях обеспечения точности результатов. Если имеется особая ситуация, то устанавливается соответствующий флаг и стоит до тех пор, пока он не будет сброшен посредством инициализации NPX (команда FINIT) или путем использования команды сброса ситуа- ции FCLEX. Так как флаги остаются установленными, они обеспечива- ют кумулятивную запись любых ошибок, возникающих в процессе обра- ботки. Другой способ обработки особых ситуаций заключается в размас- кировании одной или более ситуаций и разрешении прерываний в сло- ве управления NPX. В этом режиме, если NPX обнаруживает особую ситуацию, он сигнализирует прерыванием и требует, чтобы главный центральный процессор обработал ситуацию. Тем не менее, NPX не всегда связан с линией запроса прерывания центрального процессо- ра! Для размещения запросов прерываний NPX требуется внешняя схе- ма обработчика прерываний. Если Ваша система не поддерживает внешние прерывания NPX, то не разрешайте их! Если Ваша система поддерживает внешние прерывания и Вы разре- шили их, то необходимо обеспечить обработчик особых ситуаций, в то время, когда NPX прерывает работу главного центрального про- цессора. Для определения причины возникшей проблемы программа центрального процессора должна прочитать слово состояния NPX. Ес- ли Вы потребуете, то Ваш обработчик ситуаций тоже может опреде- лить команду и операнд, приведшие к возникновению проблемы, путем исследования указателей команды и операнда NPX. Для получения этой информации обработчик ситуаций должен выполнить одну из ко- манд NPX, FSTENV или FSAVE. Эти команды записывают в память глав- ного центрального процессора по меньшей мере содержание пяти ре- гистров управления NPX (слово состояния, слово управления, слово признака, указатель команды и указатель операнда). Обработчик си- туаций может восстановить информацию из памяти и обработать ее. Если Вы хотите получить более полное представление об этих ре- гистрах, то изучите листинг 10-1 раздела "Примеры программирова- ния NPX с помощью MASM", содержащий пример программы, которая сначала сохраняет эту информацию, а затем декодирует ее. Таблица 10-6 Установленные по умолчанию ответы на особые ситуации NPX. (Ситуации замаскированы) ДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Особая ситуация і Замаскированный ответ ДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Точность і Возвращает округленный результат Потеря значимости і Денормализованный результат Переполнение і Возвращает бесконечность со знаком Деление на ноль і Возвращает бесконечность со знаком . і операнда - 10-19 - ДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Особая ситуация і Замаскированный ответ ДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Денормализованный і Если операнд памяти, то игнорируется операнд і Если операнд регистра, то переводит в . і "ненормализованное" и оценивает снова Неверная операция і Если один операнд NAN, то возвращает . і его. Если оба операнда NAN, то возвра- . і щает тот, который имеет большее абсо- . і лютное значение. Если ни один из опе- . і рандов не является NAN, то возвращает . і неопределенность ДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Использование средств MS-DOS с NPX Единственное отличие написания программ с использованием NPX от написания программа без его использования заключается в том, что применение сопроцессора требует большего количества команд для применения числовых операций. Так как отличие видно только на уровне команд, единственными средствами MS-DOS, которым нужно знать о NPX, являются MASM и DEBUG. Все другие средства - LINK, LIB и CREF - игнорируют наличие NPX. Использование MASM и NPX При использовании MASM с NPX программист просто вводит коман- ды NPX таким же образом, как и команды главного центрального про- цессора. Команды NPX имеют те же поля, что и команды центрального процессора: метки, коды операций, операнды и комментарии. Единс- твенное отличие кодирования команд заключается в том, что операн- дами NPX могут быть только регистры или память NPX, а операндами главного центрального процессора могут быть только его регистры или память. В случае операндов памяти две формы не отличаются. Команды NPX могут использовать любую из пяти следующих форм памя- ти: - Только смещение FSTSW mem_word - Только база или индекс FIADD word prt [bx] - Смещение + база или индекс FSTP base[di] - База + индекс FLDCW [bp][si] - Смещение + база + индекс FILD [bp]table[di] ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і ВНИМАНИЕ і і MASM версии 1.25 имеет ошибку, которая приводит к і і обмену кодов операций FSUB c FSUBR или FDIV c FDIVR и і і наоборот, если любой из них использован в "классической" і і форме (без определения операндов). Если Вы пользуетесь і і более старой версией MASM, точно определяйте операнды и і і тип этих команд, например: і і FSUBP ST(1),ST і і FDIVRP ST(1),ST і і Помните, что классическая форма всегда использует і і форму выталкивания команды из стека. і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ - 10-20 - NPX переключатели MASM - /r и /s После записи программы в файл, необходимо использовать MASM для ее трансляции. Если применяется стандартная командная строка MASM, то каждая встреченная команда NPX выдает синтаксическую ошибку. Это происходит из-за того, что в режиме нормальной работы MASM ничего не знает о NPX. Для трансляции команд NPX надо приме- нять переключатель командной строки /r (реальный режим), что ука- зывает MASM на наличие в исходном файле команд NPX: A:>masm test.asm test.obj test.lst test.crf/r Благодаря этому MASM узнает, что транслируемая программа предназначена для выполнения с реальным NPX. MASM затем генериру- ет правильные коды операций NPX с префиксом кода операции FWAIT, если не используется одна из команд FN. (Тем не менее, обра- тите внимание, что хотя команда NPX FNOP начинается с FN, MASM генерирует префикс FWAIT.) MASM имеет еще один переключатель, который указывает ему на необходимость трансляции команды NPX. Это переключатель /e (режим эмуляции). Переключатель /e почти идентичен переключателю реаль- ного режима, единственное отличие заключается в том, что команды no-wait (FN) не транслируются. Этот переключатель нужен поль- зователям, имеющим эмуляционные библиотеки, которые для эмуляции программ могут заменять коды операций NPX вызовами главного цент- рального процессора. Так как MASM не имеет такую эмуляционную библиотеку и нет необходимости в ее использовании, если Вы имеете реальное NPX, то мы больше не будем обсуждать эту тему. Типы данных NPX в MASM Вы теперь знаете, что NPX поддерживает семь различных типов данных: слово; короткое и длинное целое; короткое и длинное ве- щественное; упакованный двоично-десятичный код; и вещественное с плавающей запятой. Для использования этих типов данных в памяти должны быть определены правильные ячейки. В таблице 10-7 показано соответствие между типами данных NPX и методами, применяемыми в MASM для их определения и обращения к ним. Ячейки памяти распределяются с помощью директив определения данных MASM (dw, dd, dq, или dt) и знака вопроса (?), следующего за ними. Этот формат приказывает MASM зарезервировать пространс- тво, но не инициализировать его. Для инициализации зарезервиро- ванной ячейки, предназначенной для отдельного значения веществен- ного числа, MASM обеспечивает три различных формы: экспоненциальный формат без экспоненты, экспоненциальный формат с экспонентой и реальную (R) форму. Каждая из этих форм может быть использована с любой из больших директив "определения данных" следующим образом: double dd 3.14159 ; экспоненциальный без экспоненты quad dq 1.23456E + 03 ; экспоненциальный с экспонентой tenbyte dt 0123456789ABCDEF0123R ; реальный - 10-21 - Таблица 10-7 Сравнение типов данный NPX и MASM ДДДДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДВДДДДДДДВДДДДДДДДДДВДДДДДДДДДДД Тип данных іТип данных і Размері Дирек-і Имя іСовмести- NPX і главного і в і тива іоперанда імость с і ЦП і байтахі MASM і іNPX ДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДЕДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДД Целое слово і Слово і 2 і dw і word prt і Да Короткое і Двойное і і і і целое і слово і 4 і dd і dword ptrі Да Короткое і Двойное і і і і вещественное і слово і 4 і dd і dwort ptrі Нет Длинное і Четверное і і і і целое і слово і 8 і dq і qword ptrі Да Длинное і Четверное і і і і вещественное і слово і 8 і dq і qword ptrі Нет Упакованный і Десятый і і і і Форма BCD і байт і 10 і dt і tbyte ptrі "R" Плавающее і Десятый і і і і вещественное і байт і 10 і dt і tbyte ptrі Да ДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДБДДДДДДДБДДДДДДДДДДБДДДДДДДДДДД Определение вещественных чисел с помощью байта определения (db) или директив определения слова (dw) не возможно. Они могут быть инициализированы только в целые значения. Экспоненциальные форматы оцениваются в формате с плавающей запятой (знак, экспонента и мантисса), поскольку вещественный формат используется по основанию цифра-на-полубайт, поэтому шестнадцатиричное представление вещественного формата точно соот- ветствует его определению. Обратите внимание, что хотя MASM может определять веществен- ные числа как 4-битовой, так и 8-битовой длины, формат, использу- емый для инициализации этих чисел, не совместим с NPX! На рисунке 10-10 показано, как Microsoft реализует числа этих размеров. Сравнивая их с рисунком 10-2, Вы увидите, что они совсем разные. Если Вам необходимо использовать эти форматы (например, для сов- местимости с существующим программным обеспечением), то для пере- вода одного формата в другой Вы можете написать программу преоб- разования. Длинное ЪДДДДВДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї вещественное і 81hіSі Мантисса 55 бит і і АДДДДБДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ 6356 55 54 і АДДД 1.0 предполагается і і Короткое і Смещенная ЪДДДДВДВДДДДДДДДДДДДДДДДДДї вещественное АДДДэкспонентаДДДДДі 81hіSі Мантисса 23 битаі в Microsoft MASM 129.0 АДДДДБДБДДДДДДДДДДДДДДДДДДЩ 31 24 23 22 АД1.0 предполагается Рис.10-10. Форматы вещественных чисел Microsoft MASM. Использование DEBUG с NPX DEBUG всегда знает о командах NPX. Этим объясняет то, что - 10-22 - иногда при попытке "дисассемблирования" памяти, DEBUG выдает странные команды. (Одним из методов, используемых при отладке, является заполнение неиспользуемой памяти шестнадцатиричным сло- вом DEAD. Этот характерный образец позволяет программисту быстро определить, сколько памяти изменено. Тем не менее, DEBUG дисас- семблирует это как FISUBR WORD PTR [DI + ADDE].) Хотя программа DEBUG постоянно находится в режиме NPX, она не всегда распознает команды NPX. Программа не выводит на экран и не позволяет транслировать команды формы FN. DEBUG распознает FWAIT как отдельную команду кода операции NPX, чем она реально и является. Следовательно, DEBUG декодирует команду FN как стандартную команду, которая не будет иметь префикса FWAIT. В противоположность MASM, DEBUG не вставляет автоматически префикс FWAIT в стандартные команды NPX. Вы должны помнить о том, что необходимо вручную транслировать FWAIT при вводе команды NPX. Вы должны также помнить, что при определении операндов в DEBUG, требуется указывать программе, какой размер имеет операнд: FLD TBYTE PTR [200] Скобки требуются для того, чтобы проинформировать DEBUG о том, что число представляет собой адрес, а не прямое значение. Отладка регистров NPX Единственное, что DEBUG не может сделать, так это отобразить состояние NPX или содержание любого из его регистров. Если Вы ре- шили проверить какие-либо регистры NPX, то сначала надо сделать так, чтобы NPX записал данные в общую память. Для того, чтобы помочь Вам отлаживать программы NPX, мы пред- лагаем программу dump87, содержащуюся в следующем разделе, "При- меры программирования NPX с помощью MASM". Эта программа исполь- зует команду FSAVE для записи состояния NPX с последующим отображением его в более понятной форме на экране дисплея. Прог- ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДД ДДї і Байт младшего адреса і Байт старшего адреса і0,1,2 байта/ і ГДДВДДВДДВДДВДДВДДДДДВДДЕДДДДДВДДВДДДДДВДДДДДДДДЕДДДДДДДДДД \ \ і (1)і 1і 1і 0і 1і 1і OP-Aі 1і aa і 1і OP-Bі mmm іСмещение / / і ГДДЕДДЕДДЕДДЕДДЕДДДДДЕДДЕДДДДДЕДДБДДДДДЕДДДДДДДДЕДДДДДДДДД \ \ і (2)і 1і 1і 0і 1і 1і ** і *і aa і OP-B і mmm іСмещение / / і ГДДЕДДЕДДЕДДЕДДЕДДВДДЕДДЕДДВДДЕДДДДДДДДЕДДДДДДДДЕДДДДДДДДДД \ \ДЩ (3)і 1і 1і 0і 1і 1і Rі Pі *і 1і 1і OP-B і m і ГДДЕДДЕДДЕДДЕДДЕДДВДДЕДДЕДДВДДЕДДВДДДДДБДДДДДДДДґ (4)і 1і 1і 0і 1і 1і 0і 0і 1і 1і 1і 1і OP і ГДДЕДДЕДДЕДДЕДДЕДДВДДЕДДЕДДВДДЕДДЕДДДДДДДДДДДДДДґ (5)і 1і 1і 0і 1і 1і 0і 1і 1і 1і 1і 1і OP і АДДБДДБДДБДДБДДБДДБДДБДДБДДБДДБДДБДДДДДДДДДДДДДДЩ 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 АДДДДДДДДДДДДДДБДДДДДДДДЩ Переход Код NPX і OP-A и OP-B і АДДДДДэтоДДДДДДЩ разделенный код операции ДДДДДДДДДДДДДДДДДДД * - OP-A ** - Формат Рис.10-11. Форматы кодировки команд - 10-23 - рамма может быть помещена в библиотеку или включена в трансляцию для вызова ее при появлении необходимости проверить вычисления NPX. Более полно программа рассматривается в следующем разделе. Форматы кодировки команд При чтении шестнадцатиричных дампов команды NPX можно узнать по наличию либо кода операции FWAIT (9B), либо характерных управ- ляющих кодов, с D8 по DF (шестнадцатиричное). На рисунке 10-11 показаны различные формы, которые может принимать команда, но все команды начинаются с комбинации битов 11011. Примеры программирования NPX с помощью MASM Даже имея хорошие технические знания о NPX и копию справочни- ка по командам (который нужен для серьезного программирования NPX), трудно понять работу NPX, не выполнив несколько упражнений. Так как мы не можем предоставить Вам компьютер и NPX, мы продела- ем следующее. Мы дадим несколько нетривиальных примеров программ, которые помогут Вам лучше понять то, как работает NPX, и присту- пить к созданию своей собственной библиотеки программ для NPX. Команды FWAIT и FINIT Подчеркнем еще раз, что главный центральный процессор пред- назначен для использования результатов NPX и сначала должен, пос- лав команду FWAIT, убедиться в том, что NPX закончило работу. Также важно понять, что NPX должно инициализироваться в нача- ле программы командой FINIT, и мы обещали Вам оказать помощь в этой ситуации. Необходимо перед выполнением операций привести NPX в состояние готовности. Программа DUMP87 Ранее мы отметили, что программа DEBUG не имеет возможности проверить содержимое или состояние NPX. В листинге 10-1 представ- лена программа, которая выполняет дамп содержания NPX и произво- дит его проверку. Листинг 10-1. DUMP87 - cредство отладки NPX ---------------------------------------------------------------- PAGE 60,132 ; широкий листинг #.8087 ; разрешить трансляцию команд 8087 NPX ;============================================================= ; Р Е А Л И З А Ц И Я Б И Б Л И О Т Е К И ; PUBLIC dump87 ; определена библиотечная программа ; #MODEL SMALL ; #.CODE EXTRN bin2hex:NEAR ; вызов библиотечной программы - 10-24 - ;============================================================= ; D U M P 8 7 - С Р Е Д С Т В О О Т Л А Д К И 8 0 8 7 ; ; Эта процедура выполняет дамп полного состояния расширения ; числовой обработки (NPX) фирмы Intel (8087, 80287 и 80387) в ; стек, затем форматирует и выводит его на экран. ; ; Требования к установке: НЕТ ; Требования к стеку: свободно 108 байтов стека ; ; ...wd -- Слово, определенное для полей бита различных слов. ; Определенные структуры получают преимущество ввиду того, что ; структуры прерываний SW и CW соответствуют друг другу. ;------------------------------------------------------------- ; М А К Р О О П Р Е Д Е Л Е Н И Я ; ; ;; Отобразить символ (из DL) @DisChr MACRO char push ax push dx mov dl,&char mov ah,02h int 21h pop dx pop ax ENDM ;; ;; Отобразить строку по метке @DisStr MACRO string push ax push dx mov dx,offset &string mov ah,09h int 21h pop dx pop ax ENDM ; ;; Отобразить строку (из DS:DX) @Display MACRO mov ah,09h int 21h ENDM ; #.DATA ;------------------------------------------------------------- ; О П Р Е Д Е Л Е Н И Я С Т Р У К Т У Р ; intrpt record master:1,nul0:1,pr:1,un:1,ov:1,zd:1,de:1,inv_op:1 comtrol record infc:1,rndc:2,prec:2 status record busy:1,c3:1,stp:3,c2:1,c1:1,c0:1 tag record onetag:2 ipwd record ipseg:4,nul2:1,opcode:11 ; код операции и команда ; ...указатель opwd record opseg:4,nul3:12 ; сегмент операнда указателя expwd record sign:1,exp:15 ; знак и экспонента - 10-25 - ; ; Основная структура среды: enviro STRUC cw87 dw ? ; слово управления cw87 dw ? ; слово состояния tw87 dw ? ; слово признака ipo87 dw ? ; смещение указателя команды ips87 dw ? ; сегмент указателя команды и кода операции opo87 dw ? ; смещение указателя операнда ops87 dw ? ; сегмент указателя операнда ; ; Структура регистра: fltreg STRUC man87 dq ? ; мантисса (значащая часть) exp87 dw ? ; экспонента и знак fltreg ENDS ; ; Структура сохранения состояния: state87 STRUC db size enviro dup (?) ; заголовок среды reg87 db size fltreg * 8 dup (?) ; 8 регистров данных state87 ENDS ; dump87s STRUC ; формат стека для ; ; ... dump 87 rec87 db size state87 dup (?) ; место для состояния NPX ; oldbp dw ? ; элемент базового указателя dump87s ENDS ; BASE EQU [bp - size dump87s] ; индекс структуры ; #.CODE ;------------------------------------------------------------- ; Н А Ч А Т Ь К О Д П Р О Г Р А М М Ы ; dump87 PROC NEAR push bp ; сохранить элемент базового указателя pushf ; сохранить флаги вызывающего оператора push ds ; сохранить сегмент данных ; ... вызывающего оператора mov bp,sp ; и установить индекс sub sp,size dump87s ; освободить пространство для ; ... локального хранения push ax ; сохранить регистры вызывающего ; ... оператора push ax push bx push cx push dx push di push si ; mov ax,cs ; установить сегмент данных для ; ... указания на эту mov ds,ax ; ... область данных программы - 10-26 - ; ; Получить копию внутреннего состояния NPX: pushf ; сохранить состояние прерывания ; ... вызывающего оператора cli ; запретить прерывания во время записи FSAVE BASE.rec87 ; сохранить состояния NPX FRSTOR BASE.rec87 ; восстановить записанное состояние FWAIT ; ждать завершения восстановления popf ; снова разрешить прерывания? ; ; Теперь мы имеем копию состояния NPX, декодируем его и ; выведем пользователю на терминал. ; ; Представление состоит из следующих пунктов ; ; ===================== NPX DUMP ========================== ; Infinity: Affine Round.......near Precision: 64 ; Inst Addr: x:xxxx Oper Addr: x:xxxx Opcode: Dxxx ; ; INT PRE UND OVR ZER DEN IIP C3 C2 C1 C0 ; Enable: x x x x x x x x x x x ; Signal: x x x x x x x <-- "x" означает неза- ; маскированное ; или сигнал ; exponent significand ; ST(x) + xxxx xxxx xxxx xxxx xxxx #0 tag ; . ; . ; . ; --------------------------------------------------------- ; ; Управление бесконечностью, округлением и точностью: @DisStr LINE1 ; начать отображение mov al,byte ptr BASE.cw87+1 ; получить слово управления and al,mask infc ; управление бесконечностью mov cl,infc shr al,cl ; условие # mul inf_siz ; смещение условия add ax,offset inf_cnd ; адрес условия mov dx,ax @Display ; @DisStr rnd_lab mov al,byte ptr BASE.cw87+1 ; получить слово управления and al,mask rndc ; управление округлением mov cl,rncd shr al,cl ; управление # mul rnd_siz ; смещение условия add ax,offset rnd_cnd ; адрес условия mov dx,ax @Display ; @DisStr pre_lab mov al,byte ptr BASE.cw87+1 ; получить слово управления and al,mask prec ; управление точностью mov cl,prec - 10-27 - shr al,cl ; управление # mul pre_siz ; смещение условия add ax,offset pre_cnd ; адрес условия mov dx,ax @Display ; ; Указатели команды и операнда, а также код операции @DisStr LINE2 ; следующая строка mov ax,BASE.ips87 ; указатель команды and ax,mask ipseg ; сегмент mov cl,ipseg shr ax,cl ; цифра mov ch,1 ; отобразить 1 call bin2hex @DisChr ':' mov ax,BASE.ipo87 ; указатель команды mov ch,4 ; смещение call bin2hex ; @DisStr opadr ; указатель операнда mov ax,BASE.ops87 ; указатель команды and ax,mask opseg ; сегмент mov cl,opseg shr ax,cl ; цифра mov ch,1 ; отобразить 1 call bin2hex @DisChr ':' mov ax,BASE.opo87 ; указатель операнда mov ch,4 ; смещение call bin2hex ; @DisStr ocode ; код операции mov ax,BASE.ips87 and ax,mask opcode or ax,0800h ; добавить бит кода операции mov ch,3 ; 3 цифры call bin2hex ; отобразить ; ; Флаги разрешения прерывания / особой ситуации: @DisStr LINE3 ; следующая строка mov al,byte ptr BASE.sw87+1 ; флаг разрешения ситуации call exception_flags ; показать состояние ; ; Коды условий: @DisStr space10 mov ah,byte ptr BASE.sw87+1 ; коды условий push ax ; (сохранить коды) mov al,30h ; (ASCII "0") and ah,mask c3 ; C3 sub ah,mask c3 ; 0 -> CY, 1 -> NC cmc ; 0 -> NC, 1 -> CY adc al,0 ; 0 -> "0", 1 -> "1" @DisChr al ; отобразить pop ax ; (сохранить коды) ; mov ch,c2 + 1 ; # отображаемых кодов next_cc: - 10-28 - @DisStr SPACE2 ; mov al,30h ; (ASCII "0") and ah,mask c2 ; C2 sub ah,mask c2 ; 0 -> CY, 1 -> NC cmc ; 0 -> NC, 1 -> CY adc al,0 ; 0 -> "0", 1 -> "1" @DisChr al ; отобразить ; shl ah,1 ; следующий код dec ch ; уменьшать на 1 ... jnz next_cc ; ... пока все не ; ... будет сделано ; ; Флаги состояния прерывания / особой ситуации: @DisStr LINE6 mov al,byte ptr BASE.sw87 ; флаг сигнала ситуации call exception_flags ; показать состояние ; ; Отобразить регистр данных: @DisStr LINE6 mov dh,8 ; # отображаемого регистра mov si,0 ; начать с регистра #0 ; register_display: @DisStr LINE8 ; регистры состояния push dx ; сохранить счет mov al,8 ; вычислить регистр # sub al,dh add al,30h ; перевести в ASCII @DisChr al ; и отобразить pop dx ; ; Знак регистра данных: @DisStr paren ; следующим идет знак mov ax,word ptr BASE.reg87[si].exp87 test ax,mask sign ; что это? jnz sign_minus @DisStr plus jmp show_exponent sign_minus: @DisStr minus ; ; Экспоненциальная часть регистра данных: show_exponent: and ax,mask exp ; получить экспоненту xor cx,cx ; четыре символа call bin2hex ; и отобразить @DisStr space3 ; mov di,si ; основание регистра add di,offset exp87 ; положение мантиссы mov dl,4 ; 4 слова на регистр ; ; Отобразить значащую часть регистра данных: show_significand: sub di,2 ; указать начало слова - 10-29 - mov ax,word ptr Base.reg87[di] call bin2hex ; и отобразить @DisStr SPACE1 dec dl jnz show_significand ; ; Правильный номер регистра: @DisStr truenum mov al,byte ptr BASE.sw87+1 ; получит указатель стека and al,mask stp mov cl,stp shr al,cl ; иметь указатель стека ; mov cl,8 ; преобразовать счетчик в sub cl,dh ; ... значение от 0 до 7 add al,cl ; # текущего регистра ; push ax ; сохранить номер регистра add al,30h ; преобразовать в ASCII @DisChr al ; и отобразить ; @DisStr SPACE2 ; переход в поле TAG ; ; Состояние слова признака: mov ax,BASE.tw87 ; получить слово признака pop cx ; получить номер регистра ; ... в CL shl cl,1 ; многократно по 2 shr ax,cl ; получить соответствующее ; ... слово признака and ax,mask tag ; push dx mul tag_siz ; смещение условия add ax,offset tag_cnd ; адрес условия mov dx,ax @Display ; показать состояние признака pop dx ; ; Для данного регистра все выполнено! add si,size fltreg ; следующий регистр dec dh ; меньше на 1 jz finished jmp register_display ; пока все не выполнено ; ; Все выполнено для всех регистров! ; finished: @disStr LINE9 ; все сделано! ; ; Восстановить главный центральный процессор в первоначальное ; состояние. Начать с сохраненных регистров. pop si ; восстановить регистры... ; ... вызывающего оператора pop di pop dx pop cx - 10-30 - pop bx pop ax mov sp,bp ; восстановить стек pop ds ; восстановить сегмент данных popf ; восстановить флаги... ; ... вызывающего оператора pop bp ; восстановить весь... ; ... базовый указатель ret ; вернуться после завершения ; ;------------------------------------------------------------- ; Отобразить подпрограмму для вывода на экран состояния маски ; и сигнала особых ситуаций. ; Проверить байт в AL на наличие битов, соответствующих ; флагам особых ситуаций. ; exception_flags PROC NEAR test al,mask master ; главное управление call mark_it ; mov cl,pr ; следующим идет флаг PR ror al,cl ; перейти к первой позиции inc cl ; считать 1 > бита # ; test_exception: test al,1 ; флаг установлен? call mark_it rol al,1 ; следующий шаг dec cl ; следить за счетом jnz test_exception ; продолжать до завершения ret ; ;------------------------------------------------------------- ; Отметить результат в соответствии с установленными флагами ; записи. ; mark_it PROC NEAR jz mark_space @DisStr marky ret mark_space: @DisStr markn ret mark_it ENDP ; exception_flags ENDP ; #.DATA ;------------------------------------------------------------- ; З А П И С Ь Л О К А Л Ь Н Ы Х К О Н С Т А Н Т DUMP87 ; ; ------- этот раздел только считывается ------- ; ; "_lab" - метка раздела ; "_cnd" - условие для метки ; "_siz" - число байтов в условии ; - 10-31 - @CRet MACRO ;; новое макроопределение строки db 0Dh,0Ah ENDM ; LINE1 EQU $ @CRet db '=====================NPX DUMP ==================== db '===' @CRet db 'Infinity: $' rnd_lab db ' Round:........ $' ; метка pre_lab db ' Precision: $' ; метка inf_lab db 7 inf_cnd db 'Proj. $' ; состояние бесконечности db 'Affine$' ; состояние бесконечности rnd_siz db 5 rnd_cnd db 'near$' ; состояние округления db 'down$' ; состояние округления db 'up $' ; состояние округления db 'chop$' ; состояние округления pre_siz db 3 pre_cnd db '24$' ; состояние точности "ret" db '**$' ; состояние точности "ret" db '53$' ; состояние точности "ret" db '64$' ; состояние точности "ret" ; LINE2 EQU $ @CRet db 'Inst Addr: $' ; "x:xxxx" opadr db ' Oper Addr: $' ; "x:xxxx" ocode db ' Opcode: D$' ; "xxx","ret","ret" ; LINE3 EQU $ @CRet @CRet db ' INT PRE UND OVR ZER DEN IOP' db ' C3 C2 C1 C0' db 'Masked:$' ; коды условия "ret" LINE6 EQU $ @CRet db 'Signal:$' ; "ret" marky db ' x $' markn db ' $' ; LINE8 EQU $ @CRet db 'ST($' ; "x" paren db ') $' plus db '+ $' minus db '- $' ; "xxxx" space10 db ' ' ; 10 пробелов SPACE2 EQU $ + 1 ; 2 пробела SPACE1 EQU $ + 2 ; 1 пробел space3 db ' $' ; 3 пробела ; "xxxx" 4 раза truenum db ' #$' ; " #x", чем флаг " " - 10-32 - tag_siz db 6 tag_cnd db 'Valid$' ; состояние признака db 'Zero $' ; состояние признака db 'Spec.$' ; состояние признака db 'Empty$' ; состояние признака ; LINE9 EQU $ @CRet db '----------------------------------------' db '--------' CRLF EQU $ @CRet db '$' ; #.CODE ; dump87 ENDP ;============================================================= END ; конец программ(ы) ---------------------------------------------------------------- Программа DUMP87 получает отображаемую информацию с помощью команды NPX FSAVE. Эта команда сохраняет состояние NPX в 94 бай- тах в формате, показанном на рисунке 10-12. Тем не менее, FSAVE инициализирует NPX таким же образом, как если бы была выполнена команда FINIT. Это позволяет числовой подпрограмме сохранить со- стояние NPX и затем инициализировать его одной командой, которая аналогична помещению в стек регистров и их очистке для ввода подпрограммы главного центрального процессора. Так как мы хотим продолжить обработку без прерывания, необходимо дополнить FSAVE командой FRSTOR, которая заново загружает NPX, исходя из сохра- ненной информации. Из рисунка 10-12 видно, что первые 14 байтов сохраненной ин- формации идентичны байтам, сохраненным командой FSTENV (сохранить среду). Команда FSTENV не реинициализирует NPX; скорее, она пред- назначена для предоставления программисту доступа к информации, необходимой для обработки особых ситуаций: слова состояния, а также указателей команды и операнда. Команды FSAVE и FSTENV имеют совокупную команду FLDENV, которая может перезагрузить среду, ис- ходя из сохраненной информации. Использование программы DUMP87 Завершающая часть программы ничего не делает с NPX. Она при- меняет структуру и определения записи MASM для разбиения информа- ции, полученной с помощью команды FSAVE, и представления ее поль- зователю. Формат, использованный для представления информации, описан в разделе заголовка программы. Программа, приведенная в листинге, пригодна для трансляции и включения в библиотечный файл. Если Вы выполните указанную процедуру, программа DUMP87 мо- жет быть включена в любой другой файл путем сопоставления имен сегмента и класса DUMP87, посредством описания ее как внешней и обеспечения внешней программы BIN2HEX. Один из способов использо- вания DUMP87 выглядит следующим образом: code segment para public 'code' ; библиотечный сегмент aasume cs:code,ds:code,es:code,ss:code extrn dump87:near ; БИБЛИОТЕЧНАЯ ПРОГРАММА ORG 0100h ; ФОРМАТ .COM main proc far start: - 10-33 - FSAVE (94 байта) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї Ъ Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д ДЪДДДДДДДДДДї іі і Слово і і іуправленияі іі ГДДДДДДДДДДґ і і Слово і іі і состоянияі FSTENVі ГДДДДДДДДДДґ (14 іі і Слово і байт)і і признака і іі ЪДДДДДДДДДДВДДБДДДДДДДДДДґ і і Код і Указатель і іі і операции і команды і і ГДДДДДДДДДДЕДДДДДДДДДДДДДґ ііЪДД Знаковый бит і і Указатель і і і і і операнда і АЪДВДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДДДґ і і і і ST(0)і іЭкспонентаі Мантисса і ГДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і ST(1)і і і і ГДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і ST(2)і і і і ГДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і ST(3)і і і і ГДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і


© KOAP Open Portal 2000
 


?????? ???????????