📄 flda086.asm
字号:
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 + -