fpuexam.asm
来自「工欲善其事」· 汇编 代码 · 共 143 行
ASM
143 行
; #########################################################################
;
; FpuExam
;
;##########################################################################
; -----------------------------------------------------------------------
; This procedure was written by Raymond Filiatreault, December 2002
;
; This FpuExam function examines an 80-bit REAL number (Src) for its
; validity, its sign, a value of zero, an absolute value less than 1, and
; a value of infinity.
; The result is returned in EAX as coded bits:
; EAX = 0 invalid number
; bit 0 1 = valid number
; bit 1 1 = number is equal to zero
; bit 2 1 = number is negative
; bit 3 1 = number less than 1 but not zero
; bit 4 1 = number is infinity
; If the source was on the FPU, it will be preserved if no error is
; reported.
;
; The source can only be an 80-bit REAL number from the FPU itself or
; from memory.
;
; Only EAX is used to return error or the result of the examination. All
; other registers are preserved.
;
; -----------------------------------------------------------------------
.486
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include Fpu.inc
.data
stflags dd 0
stword dw 0
.code
; #########################################################################
FpuExam proc public lpSrc:DWORD, uID:DWORD
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;
; Because a library is assembled before its functions are called, all
; references to external memory data must be qualified for the expected
; size of that data so that the proper code is generated.
;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; the FPU will be initialized only if the source parameter is not taken
; from the FPU itself.
mov stflags,0 ;initialize flags
fclex ;clear exception flags on FPU
test uID,SRC1_FPU ;is Src taken from FPU?
jnz dest0 ;go complete process
finit
;----------------------------------------
;check source for Src and load it to FPU
;----------------------------------------
test uID,SRC1_REAL ;is Src an 80-bit REAL in memory?
jz srcerr ;no proper source identificaiton
mov eax,lpSrc
fld tbyte ptr [eax]
jmp dest0 ;go complete process
srcerr:
finit
xor eax,eax
ret
dest0:
ftst ;test number
fstsw stword ;retrieve exception flags from FPU
fwait
test stword,1 ;invalid operation?
jnz srcerr
test stword,4000h ;0 value or NAN?
jz @F
test stword,100h ;NAN or infinity
jnz examine ;go check for infinity value
or stflags,XAM_ZERO
jmp finish ;no need for checking for sign or size if 0
@@:
test stword,100h ;is number negative?
jz @F
or stflags,XAM_NEG
;check for size smaller than 1 by taking the logarithm of the absolute value
; and checking if it is negative
@@:
fld st(0) ;copy the number to get its logarithm
fabs ;make sure it is positive
fld1 ;for multiplying by 1
fxch ;for next instruction
fyl2x ;gets the logarithm * 1
ftst ;test number
fstsw stword ;retrieve status word from FPU
fstp st(0) ;get rid of the tested value
test stword,4000h ;0 or infinity?
jnz finish ;if the logarithm is 0, the value was = 1
test stword,100h ;is logarithm negative?
jz finish
or stflags,XAM_SMALL ;values less than 1 have a negative logarithm
finish:
test uID,SRC1_FPU ;check what was source
jnz @F ;leave result on FPU if it was the source
finit
@@:
mov eax,stflags
or al,1 ;to indicate source was a valid number
ret
examine: ;strictly for infinity value
fxam
fstsw stword ;retrieve result of fxam
fwait
mov ax,stword
and ah,45h ;mask C0,C2, and C3
cmp ah,5 ;test for infinity
jnz srcerr ;must be NAN
or stflags,XAM_INFINIT
jmp finish
FpuExam endp
; #########################################################################
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?