fpusize.asm
来自「工欲善其事」· 汇编 代码 · 共 153 行
ASM
153 行
; #########################################################################
;
; FpuSize
;
;##########################################################################
; -----------------------------------------------------------------------
; This procedure was written by Raymond Filiatreault, December 2002
;
; This FpuSize function computes the exponent of a number (Src) as if it
; were expressed in scientific notation and returns the result as a LONG
; integer at the specified destination, unless an invalid operation
; is reported by the FPU or the definition of the parameters (with uID)
; is invalid.
;
; The source can be an 80-bit REAL number from the FPU itself or from
; memory, or an immediate DWORD value or one in memory. The FPU
; constants are not allowed as input. If the source is taken from the
; FPU, its value will be preserved there if considered valid. The
; destination must be a pointer to a LONG integer.
;
; The source is not checked for validity. This is the programmer's
; responsibility.
;
; This function simply computes the common logarithm (base 10) of the
; absolute value of the number and returns the characteristic, adjusted
; if necessary for a negative value.
;
; Only EAX is used to return error or success. All other registers are
; preserved.
;
; -----------------------------------------------------------------------
.486
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include Fpu.inc
.data
tempdw dd 0
stword dw 0
oldcw dw 0
.code
; #########################################################################
FpuSize proc public lpSrc:DWORD, lpDest: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.
fclex ;clear exception flags on FPU
test uID,SRC1_FPU ;is Src taken from FPU?
jz @F
fld st(0) ;copy it to preserve the original value
jmp dest0 ;go complete process
@@:
finit
;----------------------------------------
;check source for Src and load it to FPU
;----------------------------------------
mov eax,lpSrc
test uID,SRC1_REAL ;is Src an 80-bit REAL in memory?
jz @F
fld tbyte ptr [eax]
jmp dest0 ;go complete process
@@:
test uID,SRC1_DMEM ;is Src a 32-bit integer in memory?
jz @F
fild dword ptr [eax]
jmp dest0 ;go complete process
@@:
test uID,SRC1_DIMM ;is Src an immediate 32-bit integer?
jz srcerr ;no correct flag for Src
mov tempdw,eax
fild tempdw
jmp dest0 ;go complete process
srcerr:
finit
xor eax,eax
ret
dest0:
fabs ;insures a positive value
ftst ;check the value on the FPU
fstsw stword ;store the result
fwait
test stword,4000h ;test it for NAN or zero value
jz @F ;not NAN or zero
test stword,100h ;test for NAN
jnz srcerr ;invalid number or infinity
mov eax,80000000h ;code it for 0 value
jmp finish ;this avoids an invalid operation if computing
;the logarithm of zero was attempted
@@:
fld1
fldl2t ;load log2(10)
fdiv ;->1/[log2(10)]
fxch ;set up registers for next operation
fyl2x ;->[log2(x)]/[log2(10)] = log(x) base 10
fstcw oldcw ;get current control word
fwait
mov ax,oldcw
or ax,0c00h ;code it for truncating
mov stword,ax
fldcw stword ;change rounding code of FPU to truncate
fist tempdw ;store integer result at temporary address
fldcw oldcw ;load back the former control word
mov eax,tempdw
ftst ;test logarithm for its sign
fstsw stword ;get result
fwait
test stword,100h ;check it negative
jz @F
dec eax ;for scientific notation, the mantissa of a
;logarithm must always be positive. If negative
;its characteristic needs to be decremented.
@@:
fstp st(0) ;get rid of the logarithm
finish:
push ebx
mov ebx,lpDest
mov [ebx],eax
pop ebx
or al,1 ;to insure EAX!=0
ret
FpuSize endp
; #########################################################################
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?