fpuxexpy.asm
来自「工欲善其事」· 汇编 代码 · 共 207 行
ASM
207 行
; #########################################################################
;
; FpuXexpY
;
;##########################################################################
; -----------------------------------------------------------------------
; This procedure was written by Raymond Filiatreault, December 2002
;
; Src1^Src2 = antilog2[ log2(Src1) * Src2 ] -> Dest
;
; This FpuXexpY function raises a number (Src1) to a power (Src2)
; with the FPU and returns the result as an 80-bit REAL number at the
; specified destination (the FPU itself or a memory location), unless an
; invalid operation is reported by the FPU or the definition of the
; parameters (with uID) is invalid.
;
; Either the number or the power can be an 80-bit REAL number from the
; FPU itself or from memory, an immediate DWORD value or one in memory,
; or one of the FPU constants. The base number (Src1) must be positive.
;
; The sources are not checked for validity. This is the programmer's
; responsibility.
;
; 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
.code
; #########################################################################
FpuXexpY proc public lpSrc1:DWORD, lpSrc2: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 neither of the two source parameters
;is taken from the FPU itself.
fclex ;clear exception flags on FPU
test uID,SRC1_FPU or SRC2_FPU ;is data taken from FPU?
jnz @F
finit
;----------------------------------------
;check source for Src1 and load it to FPU
;----------------------------------------
@@:
mov eax,lpSrc1
test uID,SRC1_FPU ;is Src1 taken from FPU?
jnz src2 ;check next parameter Src2 for exponent
test uID,SRC1_REAL ;is Src1 an 80-bit REAL in memory?
jz @F
fld tbyte ptr [eax]
jmp src2 ;check next parameter Src2 for exponent
@@:
test uID,SRC1_DMEM ;is Src1 a 32-bit integer in memory?
jz @F
fild dword ptr [eax]
jmp src2 ;check next parameter Src2 for exponent
@@:
test uID,SRC1_DIMM ;is Src1 an immediate 32-bit integer?
jz @F
mov tempdw,eax
fild tempdw
jmp src2 ;check next parameter Src2 for exponent
@@:
test uID,SRC1_CONST ;is Src1 one of the FPU constants?
jnz @F ;otherwise no correct flag for Src1
srcerr:
finit
xor eax,eax
ret
@@:
test eax,FPU_PI
jz @F
fldpi ;load pi (3.14159...) on FPU
jmp src2 ;check next parameter Src2 for exponent
@@:
test eax,FPU_NAPIER
jz srcerr ;no correct CONST flag for Src1
fld1
fldl2e
fsub st,st(1)
f2xm1
fadd st,st(1)
fscale
fxch
fstp st(0)
;----------------------------------------
;check source for Src2 and load it to FPU
;----------------------------------------
src2:
mov eax,lpSrc2
test uID,SRC2_FPU ;is Src2 taken from FPU?
jz @F ;check next source for Src2
test uID,SRC1_FPU ;is Src1 the same source
jz src21
fld st(0) ;copy itself on FPU
src21:
fxch
jmp dest0 ;go complete process
@@:
test uID,SRC2_REAL ;is Src2 an 80-bit REAL in memory?
jz @F
fld tbyte ptr [eax]
jmp dest0 ;go complete process
@@:
test uID,SRC2_DMEM ;is Src2 a 32-bit integer in memory?
jz @F
fild dword ptr [eax]
jmp dest0 ;go complete process
@@:
test uID,SRC2_DIMM ;is Src2 an immediate 32-bit integer?
jz @F
mov tempdw,eax
fild tempdw
jmp dest0 ;go complete process
@@:
test uID,SRC2_CONST ;is Src2 one of the FPU constants?
jz srcerr ;no correct flag for Src2
test eax,FPU_PI
jz @F
fldpi ;load pi (3.14159...) on FPU
jmp dest0 ;go complete process
@@:
test eax,FPU_NAPIER
jz srcerr ;no correct CONST flag for Src1
fld1
fldl2e
fsub st,st(1)
f2xm1
fadd st,st(1)
fscale
fxch
fstp st(0)
dest0:
fxch ;set up FPU registers for next operation
fyl2x ;->log2(Src1)*exponent
;the FPU can compute the antilog only with the mantissa
;the characteristic of the logarithm must thus be removed
fld st(0) ;copy the logarithm
frndint ;keep only the characteristic
fsub st(1),st ;keeps only the mantissa
fxch ;get the mantissa on top
f2xm1 ;->2^(mantissa)-1
fld1
fadd ;add 1 back
;the number must now be readjusted for the characteristic of the logarithm
fscale ;scale it with the characteristic
fstsw stword ;retrieve exception flags from FPU
fwait
test stword,1 ;test for invalid operation
jnz srcerr ;clean-up and return if error
;the characteristic is still on the FPU and must be removed
fxch ;get the characteristic on top
fstp st(0) ;"pop" it
mov eax,lpDest
test uID,DEST_FPU ;check where result should be stored
jnz @F ;leave result on FPU if so indicated
fstp tbyte ptr [eax] ;store result at specified address
@@:
or al,1 ;to insure EAX!=0
ret
FpuXexpY endp
; #########################################################################
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?