fputexpx.asm

来自「工欲善其事」· 汇编 代码 · 共 155 行

ASM
155
字号
; #########################################################################
;
;                             FpuTexpX
;
;##########################################################################

  ; -----------------------------------------------------------------------
  ; This procedure was written by Raymond Filiatreault, December 2002
  ;
  ;            10^(Src) = antilog2[ log2(10) * Src ] -> Dest
  ;
  ; This FpuTexpX function computes the base 10 antilogarithm of a number.
  ; It raises 10 to the power of the Src number 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.
  ;
  ; The exponent 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 source is 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

; #########################################################################

FpuTexpX 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 data taken from FPU?
      jnz   dest0
      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    @F
      mov   tempdw,eax
      fild  tempdw
      jmp   dest0             ;go complete process
@@:
      test  uID,SRC1_CONST    ;is Src one of the FPU constants?
      jnz   @F                ;otherwise no correct flag for Src

srcerr:
      finit
      xor   eax,eax
      ret

@@:
      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 Src
      fld1
      fldl2e
      fsub  st,st(1)
      f2xm1
      fadd  st,st(1)
      fscale
      fxch
      fstp  st(0)

dest0:
      fldl2t                  ;->log2(10)
      fmul                    ;->log2(10)*Src
      
;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
    
FpuTexpX endp

; #########################################################################

end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?