fldm086.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 439 行 · 第 1/2 页

ASM
439
字号
          _quif ne              ; - ...
          dec   BX              ; - decrement counter
          or    CX,4[DI]        ; - ...
          _quif ne              ; - ...
          dec   BX              ; - decrement counter
          or    CX,6[DI]        ; - ...

;         if CX = 8000h, then op2 is a power of 2, just return op1 with
;         appropriate sign and exponent
          xchg  SI,DI           ; - flip pointers
          cmp   CX,8000h        ; - if op2 is a power of 2
          je    pow2_hop        ; - then do special calc.
          xchg  SI,DI           ; - flip pointers back

          or    CX,CX           ; - test high order word
          _quif ne              ; - quit if op2 is not 0
          test  DX,7FFFh        ; - quit if exponent is not 0
          _quif ne              ; - ...
          mov   AX,CX           ; - set result to 0
          mov   BX,CX           ; - ...
          mov   DX,CX           ; - ...
          mov   SI,CX           ; - ...
ifdef _BUILDING_MATHLIB
          pop   DS              ; - restore DS
endif
          ret                   ; - return 0
        _endguess               ; endguess
        or      BX,BX           ; if op2 has more lower word zeros than op1
        _if     s               ; then
          xchg  SI,DI           ; - flip the arguments to reduce # of multiplies
        _endif                  ; endif

        mov     CX,AX           ; calc. sign of result
        xor     CX,DX           ; ...
        and     CX,8000h        ; ...
        and     AH,7Fh          ; isolate exponent
        and     DH,7Fh          ; ...

        _guess                  ; guess: overflow
          add   AX,DX           ; - determine exponent of result
          sub   AX,3FFEh        ; - remove extra bias
          cmp   AX,-3FFEh       ; - quit if exponent is negative
          _quif ae              ; - . . .
          cmp   AX,7FFFh        ; - quit if not overflow
          _quif b               ; - . . .
          jmp   mul_oflow       ; - handle overflow
        _endguess               ; endguess
        cmp     AX,-64          ; if exponent is too small
        _if     l               ; then underflow
          sub   AX,AX           ; - set result to 0
          mov   BX,AX           ; - ...
          mov   CX,AX           ; - ...
          mov   DX,AX           ; - ...
          mov   SI,AX           ; - ...
ifdef _BUILDING_MATHLIB
          pop   DS              ; - restore DS
endif
          ret                   ; - return
        _endif                  ; endif

        push    BP              ; save BP
        push    CX              ; save sign of result
        push    AX              ; save exponent

        sub     BX,BX           ; zero BX
        push    BX              ; allocate and zero accumulator
        push    BX              ; ...
        push    BX              ; ...
        push    BX              ; ...
        push    BX              ; ...
        push    BX              ; ...
        push    BX              ; ...
        push    BX              ; ... (sticky bits)
        push    6[DI]           ; push multiplicand onto stack
        push    4[DI]           ; ...
        push    2[DI]           ; ...
        push    [DI]            ; ...
        mov     BP,SP           ; point to multiplicand and accumulator
        push    6[SI]           ; push multiplier onto stack
        push    4[SI]           ; ...
        push    2[SI]           ; ...
        push    [SI]            ; ...

        _loop                   ; loop (until SP=BP)
          pop   SI              ; - get next word of multiplier from stack
          mov   BX,SP           ; - get access to stack
          mov   DI,SS:14+0[BX]  ; - get low order word for sticky bits
          or    SI,SI           ; - if multiplier not zero
          _if   ne              ; - then
            sub   CX,CX         ; - - zero CX
            mov   AX,[BP]       ; - - get low order word of multiplicand
            mul   SI            ; - - do multiply
            mov   DI,AX         ; - - save result
            mov   BX,DX         ; - - ...
            mov   AX,2[BP]      ; - - get next word of multiplicand
            mul   SI            ; - - do multiply
            add   BX,AX         ; - - accumulate result
            adc   CX,DX         ; - - ...
            mov   AX,4[BP]      ; - - get next word of multiplicand
            mul   SI            ; - - do multiply
            add   CX,AX         ; - - accumulate result
            adc   DX,0          ; - - ...
            xchg  DX,SI         ; - - answer in SI, multiplier in DX
            mov   AX,6[BP]      ; - - get last word of multiplicand
            mul   DX            ; - - do multiply
            add   AX,SI         ; - - accumulate result
            adc   DX,0          ; - - ...
            mov   SI,BP         ; - - save BP
            mov   BP,SP         ; - - get access to stack
            add   DI,14+0[BP]   ; - - accumulate result
            adc   14+2[BP],BX   ; - - ...
            adc   14+4[BP],CX   ; - - ...
            adc   14+6[BP],AX   ; - - ...
            adc   14+8[BP],DX   ; - - ...
            mov   BP,SI         ; - - restore BP
          _endif                ; - endif
          or    8[BP],DI        ; - update the sticky bits
          cmp   SP,BP           ; - check to see if we are done
        _until  e               ; until done
donemul:
        mov     DI,14+0[BP]     ; get result
        mov     DX,14+2[BP]     ; ...
        mov     CX,14+4[BP]     ; ...
        mov     BX,14+6[BP]     ; ...
        mov     AX,14+8[BP]     ; ...
;
;       now have AX:BX:CX:DX:DI containing the fraction
;
        mov     BP,8[BP]        ; get sticky bits
        add     SP,8+(8*2)      ; clean up the stack
        pop     SI              ; get exponent
        _guess                  ; guess: exponent >= 0
          or    SI,SI           ; - quit if exponent < 0
          _quif s               ; - ...
          _loop                 ; - loop (normalize)
            _shl  DI,1          ; - - shift number left 1
            _rcl  DX,1          ; - - ...
            _rcl  CX,1          ; - - ...
            _rcl  BX,1          ; - - ...
            _rcl  AX,1          ; - - ...
            dec   SI            ; - - decrement exponent (doesn't change carry)
            _quif s             ; - - exit if denormal operand
          _until  c             ; - until carry
          inc   SI              ; - bump exponent back up one
          _if   e               ; - if exponent is 0
            _if   nc            ; - - if no carry from fraction
;             cmp   AX,7FFFh    ; - - - and fraction < 8000h
;             _if   le          ; - - - then
;               cmp   SP,SI     ; - - - - cmp things that aren't equal
;             _endif            ; - - - endif
            _endif              ; - - endif
          _endif                ; - endif
          _quif e               ; - exit if denormal operand
        _admit                  ; admit: exponent <= 0
          _loop                 ; - loop (number is a denormal)
            shr   AX,1          ; - - shift number right
            rcr   BX,1          ; - - ...
            rcr   CX,1          ; - - ...
            rcr   DX,1          ; - - ...
            adc   BP,0          ; - - add carry to sticky bits
            inc   SI            ; - - increment exponent
          _until  ns            ; - until back to 0
          clc                   ; - clear carry
        _endguess               ; endguess
        rcr     AX,1            ; shift fraction right once
        rcr     BX,1            ; ...
        rcr     CX,1            ; ...
        rcr     DX,1            ; ...
        _if     c               ; if guard bit is on
          or    BP,BP           ; - if no sticky bits
          _if   e               ; - then
            or    SI,SI         ; - - if exponent not 0
            _if   ne            ; - - then
              mov   BP,DX       ; - - - get low order word
              shr   BP,1        ; - - - get bottom bit
              cmc               ; - - - complement it
            _endif              ; - - endif
          _endif                ; - endif
          cmc                   ; - complement carry
          adc   DX,0            ; - round up
          adc   CX,0            ; - ...
          adc   BX,0            ; - ...
          adc   AX,0            ; - ...
          _if   c               ; - if carry            05-jul-90
            inc   SI            ; - - increment exponent
            mov   AH,80h        ; - - set fraction
          _endif                ; - endif
        _endif                  ; endif
        pop     BP              ; restore sign
        or      SI,BP           ; merge sign in with exponent
        pop     BP              ; restore BP
ifdef _BUILDING_MATHLIB
        pop     DS              ; restore DS
endif
        ret                     ; return

mul_denormal:
        pop     SI              ; restore sign
        pop     BP              ; restore BP
ifdef _BUILDING_MATHLIB
        pop     DS              ; restore DS
endif
        ret                     ; return

        endproc ___LDM


ifdef _BUILDING_MATHLIB

        endmod

        endf    equ end
else
        endf    equ <>

endif

endf

⌨️ 快捷键说明

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