⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flda086.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:

ifdef _BUILDING_MATHLIB

include mdef.inc
include struct.inc
include xception.inc

        modstart    flda086, word

endif

;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
;<>
;<>     long double math library
;<>
;<>     inputs: AX - pointer to long double (op1)
;<>             DX - pointer to long double (op2)
;<>             BX - pointer to long double (result)
;<>
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

        xdefp   __FLDA          ; add real*10 to real*10
        xdefp   __FLDS          ; subtract real*10 from real*10
        xdefp   __FLDAC         ; add real*10 to real*10
        xdefp   __FLDSC         ; subtract real*10 from real*10
        xdefp   ___LDA          ; long double add routine

        defp    __FLDS
ifdef _BUILDING_MATHLIB
        push    DS              ; save DS
        push    SS              ; fpc code assumes parms are relative to SS
        pop     DS              ; ...
endif
        push    SI              ; save SI
        push    DI              ; save DI
        push    CX              ; save CX
        push    BX              ; save pointer to result
        mov     SI,AX           ; point to op1
        mov     DI,DX           ; point to op2
        mov     AX,8[SI]        ; get exponent+sign of op1
        mov     DX,8[DI]        ; get exponent+sign of op2
        xor     DX,8000h        ; flip the sign
        lcall   ___LDA          ; do the add
        pop     DI              ; restore pointer to result
        mov     [DI],DX         ; store result
        mov     2[DI],CX        ; ...
        mov     4[DI],BX        ; ...
        mov     6[DI],AX        ; ...
        mov     8[DI],SI        ; ...
        pop     CX              ; restore CX
        pop     DI              ; restore DI
        pop     SI              ; restore SI
ifdef _BUILDING_MATHLIB
        pop     DS              ; restore DS
endif
        ret                     ; return
        endproc __FLDS

        defp    __FLDSC
ifdef _BUILDING_MATHLIB
        push    DS              ; save DS
        push    SS              ; fpc code assumes parms are relative to SS
        pop     DS              ; ...
endif
        push    SI              ; save SI
        push    DI              ; save DI
        push    CX              ; save CX
        push    BX              ; save pointer to result
        mov     SI,AX           ; point to op1
        mov     DI,DX           ; point to op2
        mov     DX,CS:8[DI]     ; get exponent+sign of op2
        xor     DX,8000h        ; flip the sign of op2
        jmp     short _addc     ; add constant
        endproc __FLDSC

        defp    __FLDA
ifdef _BUILDING_MATHLIB
        push    DS              ; save DS
        push    SS              ; fpc code assumes parms are relative to SS
        pop     DS              ; ...
endif
        push    SI              ; save SI
        push    DI              ; save DI
        push    CX              ; save CX
        push    BX              ; save pointer to result
        mov     SI,AX           ; point to op1
        mov     DI,DX           ; point to op2
        mov     AX,8[SI]        ; get exponent+sign of op1
        mov     DX,8[DI]        ; get exponent+sign of op2
        lcall   ___LDA          ; do the add
_add9:  pop     DI              ; restore pointer to result
        mov     [DI],DX         ; store result
        mov     2[DI],CX        ; ...
        mov     4[DI],BX        ; ...
        mov     6[DI],AX        ; ...
        mov     8[DI],SI        ; ...
        pop     CX              ; restore CX
        pop     DI              ; restore DI
        pop     SI              ; restore SI
ifdef _BUILDING_MATHLIB
        pop     DS              ; restore DS
endif
        ret                     ; return
        endproc __FLDA


        defp    __FLDAC
ifdef _BUILDING_MATHLIB
        push    DS              ; save DS
        push    SS              ; fpc code assumes parms are relative to SS
        pop     DS              ; ...
endif
        push    SI              ; save SI
        push    DI              ; save DI
        push    CX              ; save CX
        push    BX              ; save pointer to result
        mov     SI,AX           ; point to op1
        mov     DI,DX           ; point to op2
        mov     DX,CS:8[DI]     ; get exponent+sign of op2
_addc:  push    CS:8[DI]        ; push constant op2 onto stack
        push    CS:6[DI]        ; ...
        push    CS:4[DI]        ; ...
        push    CS:2[DI]        ; ...
        push    CS:[DI]         ; ...
        mov     DI,SP           ; point to op2
        mov     AX,8[SI]        ; get exponent+sign of op1
        lcall   ___LDA          ; do the add
        add     SP,10           ; remove constant from stack
        jmp     _add9           ; store result
        endproc __FLDAC


; input:
;       SI - pointer to op1
;       DI - pointer to op2
;       AX - exponent+sign of op1
;       DX - exponent+sign of op2
; output:
;       SI - exponent+sign of result
;       AX:BX:CX:DX - mantissa

        defp    ___LDA
ifdef _BUILDING_MATHLIB
        push    DS              ; save DS
        push    SS              ; fpc code assumes parms are relative to SS
        pop     DS              ; ...
endif
        _guess                  ; guess: op1 is 0
          mov   CX,6[SI]        ; - quit if op1 is not 0
          or    CX,CX           ; - ...
          _quif ne              ; - ...
          or    CX,4[SI]        ; - check the lower order words
          or    CX,2[SI]        ; - ...
          or    CX,[SI]         ; - ...
          _quif ne              ; - quit if op1 is not 0
          _shl  AX,1            ; - place sign in carry
          _if   e               ; - if operand one is 0
            mov   SI,DX         ; - - get exponent+sign of op2
            mov   AX,6[DI]      ; - - load op2
            mov   BX,4[DI]      ; - - ...
            mov   CX,2[DI]      ; - - ...
            mov   DX,[DI]       ; - - ...
            mov   DI,DX         ; - - see if op2 is 0
            or    DI,CX         ; - - ...
            or    DI,BX         ; - - ...
            or    DI,AX         ; - - ...
            _if   e             ; - - if mantissa zero
              _shl  SI,1        ; - - - get rid of sign bit
              _if   ne          ; - - - if exponent not zero
                rcr   SI,1      ; - - - - restore sign bit
              _endif            ; - - - endif
            _endif              ; - - endif
ifdef _BUILDING_MATHLIB
            pop   DS            ; - - restore DS
endif
            ret                 ; - - return
          _endif                ; - endif
          rcr   AX,1            ; - put back the sign
        _endguess               ; endguess

        _guess                  ; guess: op2 is 0
          mov   CX,6[DI]        ; - quit if op2 is not 0
          or    CX,CX           ; - ...
          _quif ne              ; - ...
          or    CX,4[DI]        ; - check the lower order words
          or    CX,2[DI]        ; - ...
          or    CX,[DI]         ; - ...
          _quif ne              ; - quit if op2 is not 0
          test  DX,7FFFh        ; - quit if exponent is not 0
          _quif ne              ; - ...
          mov   DI,SI           ; - get pointer to op1
          mov   SI,AX           ; - get exponent+sign of op1
          mov   AX,6[DI]        ; - load op1
          mov   BX,4[DI]        ; - ...
          mov   CX,2[DI]        ; - ...
          mov   DX,[DI]         ; - ...
ifdef _BUILDING_MATHLIB
          pop   DS              ; - restore DS
endif
          ret                   ; - return op1
        _endguess               ; endguess

        push    BP              ; save BP
        mov     BP,DX           ; assume op1 < op2 (save op2's exponent+sign)
        sub     BX,BX           ; zero BX for sign of op1
        _shl    AX,1            ; get sign of op1
        rcr     BX,1            ; save it in BX
        shr     AX,1            ; shift exponent back into place

        sub     CX,CX           ; zero CX for sign of op2
        _shl    DX,1            ; get sign of op2
        rcr     CX,1            ; save it in CX
        shr     DX,1            ; shift exponent back into place
        add     CX,BX           ; calculate sign of result

        sub     DX,AX           ; calculate difference in exponents
        _if     ne              ; if different
          _if   b               ; - if op2 < op1
            mov   BP,AX         ; - - use exponent+sign of op1
            or    BP,BX         ; - - ... (get the sign of op1)
            neg   DX            ; - - negate the shift count

⌨️ 快捷键说明

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