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' ; библиотечный сегмент
assume 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)¦ ¦ ¦ ¦
ГД†ДДДДДДДДДД†ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
¦ ¦ ¦ ¦
ST(4)¦ ¦ ¦ ¦
ГД†ДДДДДДДДДД†ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
¦ ¦ ¦ ¦
ST(5)¦ ¦ ¦ ¦
ГД†ДДДДДДДДДД†ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
¦ ¦ ¦ ¦
ST(6)¦ ¦ ¦ ¦
ГД†ДДДДДДДДДД†ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
¦ ¦ ¦ ¦
ST(7)¦ ¦ ¦ ¦
АДБДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
¦ ¦ Смещение байта
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
¦ / +9 / +8 / +7 / +6 / +5 / +4 / +3 / +2 / +1 / +0 /
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Рис.10-12. Структура памяти FSAVE и FSTENV.
- 10-34 -
FINIT ; инициализировать NPX
.
.
.
call dump87 ; анализировать NPX
.
.
.
Программа DUMP87 требует доступа к 120 байтам стека централь-
ного процессора. При возврате информации, программа не применяет
сохранение данных, что дает большую свободу в размещении и ис-
пользовании. Как отмечено, DUMP87 требует программу BIN2HEX.
Текст программы BIN2HEX имеется в приложении А.
Использование NPX для преобразований
двоичного кода в десятичный в двоичный
Теперь, когда мы можем проверить, что делает NPX, давайте
займемся более серьезным программированием. Первое, что необходи-
мо сделать, это обеспечить понимание человеком вводимых и вывод-
ных данных NPX. Это означает представление чисел в десятичном ви-
де.
Операции с целым
Выполнить преобразование целого в двоичный код на NPX просто,
благодаря наличию команд загрузки и хранения упакованного BCD
FBLD и FBSTR. Все что нужно, это простая программа главного цент-
рального процессора для упаковки цифр BCD из строк ASCII и их
распаковки. Для перехода из десятичного кода в двоичный, загрузи-
те десятичное число с помощью FBLD и затем выполнить команду за-
писи десятичного, FBSTP.
Обратите внимание, что если преобразованные числа малы для
заполнения 16-битого регистра (или 32-битового регистра в 8038),
необязательно использовать NPX для перевода из десятичного форма-
та в двоичный. Это связано с тем, что упаковка цифр и выполнение
последовательности FBLD-FIST требует больше времени, чем следую-
щая стандартная программа преобразования с использованием "мно-
гократного сдвига":
; Предполагаемое число аккумулировано в AX, а новая цифра
; находится в регистре CL.
shr ax,1 ; имеющееся число x 2
mov bx,ax ; сохранить
shr ax,1 ; число х 4
sch ax,1 ; число х 8
add ax,bx ; (# x 8) + (# x 2) = # x 10
xor ch,ch ; подготовить к 16-битовому добавлению
add ax,cx ; добавлена следующая цифра
Преобразование в NPX маленьких чисел (от одной до трех деся-
тичных цифр) из десятичного кода в двоичный, включая время, необ-
ходимое для создания вектора упакованного BCD из строки ASCII,
продолжительнее в два раза.
Если числа больше 16 двоичных битов, главный центральный про-
цессор начинает работать медленнее, так как он должен постоянно
выполнять проверку на наличие переноса, возможных переполнений и
- 10-35 -
потерь значимости, и так далее. В диапазоне от 16 до 64 двоичных
битов, NPX выполняет операции преобразования чрезвычайно быстро!
Так как длина числа не превышает 18 десятичных цифр (что
трудно достичь!), то не требуются операции NPX, связанные с ко-
мандами загрузки и сохранения. Как только длина чисел превышает
18 цифр, они должны быть масштабированы, и мы входим в область
вещественных чисел с плавающей запятой.
Операции с плавающей запятой
Обработка преобразований между десятичными и двоичными числа-
ми в мире плавающей запятой в основном является делом масштабиро-
вания. Конечно, мы можем использовать команды FBLD и FBSTP для
ввода и вывода из NPX базисных чисел, но затем нам необходимо до-
полнить эти числа числом десять в некоторой степени. Для того,
чтобы понять, как выполняются эти операции, давайте вспомним не-
которые основные математические равенства, связанные с преобразо-
ванием чисел.
1. 10(X) = 2(X * log 10 по основанию 2)
2. E(X) = 2(X * log E по основанию 2)
3. Y(X) = 2(X * log Y по основанию 2)
4. lоg X = log 2 * log X по основанию 2
5. log X по основанию E = (log 2 по основанию E) *
(log X по основанию 2)
К счастью, NPX знает, как вычислять некоторые из этих опера-
ций и имеет константы для других. Для преобразования чисел нам