fpuarcsin.asm

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

ASM
123
字号
; #########################################################################
;
;                             FpuArcsin
;
;##########################################################################

  ; -----------------------------------------------------------------------
  ; This procedure was written by Raymond Filiatreault, December 2002
  ;
  ;                                  Src
  ;            asin(Src) = atan -------------  -> Dest
  ;                             sqrt(1-Src^2)
  ;
  ; This FpuArcsin function computes the angle in degrees or radians
  ; with the FPU corresponding to the sine value provided in the source
  ; parameter (Src) 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 source can be an 80-bit REAL number from the FPU itself or from
  ; memory. Its absolute value must be equal to or less than 1.
  ;
  ; 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
    
    stword  dw    0
    w180    dw    180
    w360    dw    360

    .code

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

FpuArcsin 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?
      jnz   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?
      jnz   @F                ;otherwise no valid ID for Src
      
srcerr:
      finit
      xor   eax,eax
      ret

@@:
      fld   tbyte ptr [eax]

dest0:
      fld   st(0)             ;copy sine value
      fmul  st,st(0)          ;sin^2
      fld1
      fsubr                   ;1-sin^2 = cos^2
      fsqrt                   ;->cos
      fpatan                  ;i.e. arctan(sin/cos) = arcsin

      fstsw stword            ;retrieve exception flags from FPU
      fwait
      test  stword,1          ;test for invalid operation
      jnz   srcerr            ;clean-up and return error

      test  uID,ANG_RAD
      jnz   @F                ;jump if angle is required in radians
      fldpi                   ;load pi (3.14159...) on FPU
      fdiv
      fimul w180              ;angle now in degrees

      ftst                    ;check for negative value
      fstsw stword            ;retrieve status word from FPU
      fwait
      test  stword,100h       ;tests for negative number
      jz    @F
      fiadd w360
      
@@:
      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
    
FpuArcsin endp

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

end

⌨️ 快捷键说明

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