fpucomp.asm

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

ASM
209
字号
; #########################################################################
;
;                             FpuComp
;
;##########################################################################

  ; -----------------------------------------------------------------------
  ; This procedure was written by Raymond Filiatreault, December 2002
  ;
  ; This FpuComp function compares one number (Src1) to another (Src2)
  ; with the FPU and returns the result in EAX as coded bits:
  ;         EAX = 0     comparison impossible
  ;         bit 0       1 = Src1 = Src2
  ;         bit 1       1 = Src1 > Src2
  ;         bit 2       1 = Src1 < Src2
  ;
  ; Either of the two sources 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. If one of the sources is from the FPU,
  ; its value will be preserved if no error is reported.
  ;
  ; None of the sources are 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
    
    stflags dd    0
    tempdw  dd    0    
    stword  dw    0

    .code

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

FpuComp proc public lpSrc1:DWORD, lpSrc2: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.

      mov   stflags,0         ;initialize flags
      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 for Src2

      test  uID,SRC1_REAL     ;is Src1 an 80-bit REAL in memory?
      jz    @F                ;check next source for Src1
      fld   tbyte ptr [eax]
      jmp   src2              ;check next parameter for Src2

@@:
      test  uID,SRC1_DMEM     ;is Src1 a 32-bit integer in memory?
      jz    @F                ;check next source for Src1
      fild  dword ptr [eax]
      jmp   src2              ;check next parameter for Src2

@@:
      test  uID,SRC1_DIMM     ;is Src1 an immediate 32-bit integer?
      jz    @F                ;check next source for Src1
      mov   tempdw,eax
      fild  tempdw
      jmp   src2              ;check next parameter for Src2

@@:
      test  uID,SRC1_CONST    ;is Src1 one of the FPU constants?
      jnz   @F                ;otherwise no valid ID for Src1

srcerr:
      finit
      xor   eax,eax           ;error code
      ret

@@:
      test  eax,FPU_PI
      jz    @F
      fldpi
      jmp   src2
@@:
      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 Src2
      fld1
      fldl2e
      fsub  st,st(1)
      f2xm1
      fadd  st,st(1)
      fscale
      fxch
      fstp  st(0)

dest0:
      fcom  st(1)
      fstsw stword            ;retrieve exception flags from FPU
      fwait
      test  stword,1          ;test for invalid operation
      jnz   srcerr            ;clean-up and return result
      mov   ax,stword
      and   ah,41h
      cmp   ah,41h            ;cannot compare
      jz    srcerr
      cmp   ah,40h
      jnz   @F
      or    stflags,CMP_EQU   ;Src2 = Src1
      jmp   finish
   @@:
      cmp   ah,1
      jnz   @F
      or    stflags,CMP_GREATER     ;Src2 < Src1
      jmp   finish
   @@:
      or    stflags,CMP_LOWER       ;Src2 > Src1

finish:
      test  uID,SRC2_FPU
      jz    @F
      fxch
   @@:
      fstp  st(0)
      test  uID,SRC1_FPU or SRC2_FPU
      jnz   @F
      finit

@@:
      mov   eax,stflags
      ret
    
FpuComp endp

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

end

⌨️ 快捷键说明

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