(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 ? ; сегмент указателя операнда
enviro ENDS
; Структура регистра:
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 ; указатель операнда