fldd086.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 502 行 · 第 1/2 页
ASM
502 行
div SI ; estimate next word of quotient
push AX ; save estimate of quotient (quot+4[BP])
mov SI,AX ; get estimate as multiplier
;
; calculate divisor * estimated quotient
;
sub CX,CX ; zero CX
mov AX,den+0[BP] ; get low order word of divisor
mul SI ; do multiply
mov DI,AX ; save result
mov BX,DX ; ...
mov AX,den+2[BP] ; get next word of divisor
mul SI ; do multiply
add BX,AX ; accumulate result
adc CX,DX ; ...
mov AX,den+4[BP] ; get next word of divisor
mul SI ; do multiply
add CX,AX ; accumulate result
adc DX,0 ; ...
xchg DX,SI ; answer in SI, multiplier in DX
mov AX,den+6[BP] ; get last word of divisor
mul DX ; do multiply
add AX,SI ; accumulate result
adc DX,0 ; ...
; result is in DX:AX:CX:BX:DI
cmp word ptr quot+6[BP],0 ; if high word of quotient is 1
_if ne ; then
add BX,den+0[BP] ; - add in divisor
adc CX,den+2[BP] ; - ...
adc AX,den+4[BP] ; - ...
adc DX,den+6[BP] ; - ...
_endif ; endif
;
; subtract estimate * divisor from dividend
;
not DX ; negate estimate * divisor
not AX ; ...
not CX ; ...
not BX ; ...
neg DI ; ...
sbb BX,-1 ; ...
sbb CX,-1 ; ...
sbb AX,-1 ; ...
sbb DX,-1 ; ...
;
; add dividend to this
;
add BX,num+0[BP] ; ...
adc CX,num+2[BP] ; ...
adc AX,num+4[BP] ; ...
adc DX,num+6[BP] ; ...
_if ne ; if high word not 0 (quotient is too big)
_loop ; - loop (find correct quotient)
sub word ptr quot+4[BP],1 ; - - decrement quotient
sbb word ptr quot+6[BP],0 ; - - ...
add DI,den+0[BP] ; - - add divisor back to dividend
adc BX,den+2[BP] ; - - ...
adc CX,den+4[BP] ; - - ...
adc AX,den+6[BP] ; - - ...
adc DX,0 ; - - ...
_until e ; - until done
_endif ; endif
mov num+0[BP],DI ; save new dividend
mov num+2[BP],BX ; ...
mov num+4[BP],CX ; ...
mov num+6[BP],AX ; ...
divloop:;_loop ; loop (for rest of estimates)
xchg DX,AX ; get high part of dividend into DX:AX
xchg AX,CX ; ...
mov SI,den+6[BP] ; get high word of divisor
cmp SI,DX ; if divisor <= high word of dividend
_if be ; then
; sub DX,SI ; - subtract divisor from dividend
; pop BX ; - restore last word of quotient
; add BX,1 ; - increment it
; _if c ; - if carry
; pop CX ; - - get next word
; add CX,1 ; - - increment it
; what about carry?
; push CX ; - - save updated quotient word
; _endif ; - endif
; push BX ; - restore last word of quotient
mov AX,0FFFFh ; - set estimate to 0xffff
_else ; else
div SI ; - estimate next word of quotient
_endif ; endif
push AX ; save estimate of quotient (quot+2[BP])
sub CX,CX ; assume quotient is 0
mov BX,CX ; ...
mov DX,AX ; ...
or AX,AX ; if quotient not zero
_if ne ; then
xchg SI,AX ; - get estimate as multiplier
;
; calculate divisor * estimated quotient
;
mov AX,den+0[BP] ; - get low order word of divisor
mul SI ; - do multiply
mov DI,AX ; - save result
mov BX,DX ; - ...
mov AX,den+2[BP] ; - get next word of divisor
mul SI ; - do multiply
add BX,AX ; - accumulate result
adc CX,DX ; - ...
mov AX,den+4[BP] ; - get next word of divisor
mul SI ; - do multiply
add CX,AX ; - accumulate result
adc DX,0 ; - ...
xchg DX,SI ; - answer in SI, multiplier in DX
mov AX,den+6[BP] ; - get last word of divisor
mul DX ; - do multiply
add AX,SI ; - accumulate result
adc DX,0 ; - ...
; result is in DX:AX:CX:BX:DI
;
; subtract estimate * divisor from dividend
;
not DX ; - negate estimate * divisor
not AX ; - ...
not CX ; - ...
not BX ; - ...
neg DI ; - ...
sbb BX,-1 ; - ...
sbb CX,-1 ; - ...
sbb AX,-1 ; - ...
sbb DX,-1 ; - ...
;
; add dividend to this
;
_endif ; endif
add BX,num+0[BP] ; ...
adc CX,num+2[BP] ; ...
adc AX,num+4[BP] ; ...
adc DX,num+6[BP] ; ...
_if ne ; if high word not 0 (quotient is too big)
sub SI,SI ; - zero correction factor
_loop ; - loop (find correct quotient)
inc SI ; - - increment adjustment
add DI,den+0[BP] ; - - add divisor back to dividend
adc BX,den+2[BP] ; - - ...
adc CX,den+4[BP] ; - - ...
adc AX,den+6[BP] ; - - ...
adc DX,0 ; - - ...
_until e ; - until done
mov DX,BP ; - save BP
mov BP,SP ; - get access to quotient
sub [BP],SI ; - adjust quotient
; _loop ; - loop
; _quif nc ; - - quit if no borrow
; add BP,2 ; - - point to next word of quotient
; sub word ptr [BP],1 ; - - adjust quotient
; _endloop ; - endloop
mov BP,DX ; - restore DX
sub DX,DX ; - zero DX
_endif ; endif
mov num+0[BP],DI ; save new dividend
mov num+2[BP],BX ; ...
mov num+4[BP],CX ; ...
mov num+6[BP],AX ; ...
dec word ptr count[BP]; - decrement loop count
_if ne ; if not done
jmp divloop ; - continue
_endif ; endif
; _until e ; until done
pop DX ; restore quotient from stack
pop CX ; ...
pop BX ; ...
pop AX ; ...
pop DI ; load high word
shr DI,1 ; get top bit of quotient
pop SI ; restore exponent of result
pop DI ; restore sign
mov SP,BP ; clean up the stack
_if c ; if top bit of quotient set
rcr AX,1 ; - shift fraction right 1 bit
rcr BX,1 ; - ...
rcr CX,1 ; - ...
rcr DX,1 ; - ...
adc DX,0 ; - round up
adc CX,0 ; - ...
adc BX,0 ; - ...
adc AX,0 ; - ...
inc SI ; - increment exponent
_endif ; endif
dec SI ; decrement exponent
_if le ; if exponent is negative (denormal number)
_loop ; - loop
shr AX,1 ; - - shift number right
rcr BX,1 ; - - ...
rcr CX,1 ; - - ...
rcr DX,1 ; - - ...
inc SI ; - - increment exponent
_until ge ; - until back to 0
sub SI,SI ; - set exponent to 0
_endif ; endif
or SI,DI ; merge sign in with exponent
pop BP ; restore BP
ifdef _BUILDING_MATHLIB
pop DS ; restore DS
endif
ret ; return
endproc ___LDD
normalize_opnd proc near
; operand is on the stack pointed to by DI
xchg DI,BP ; place address of operand in BP
_loop ; loop (normalize it)
or BX,BX ; - check high word for 0
_quif ne ; - quit if not zero
xchg [BP],BX ; - shift operand left 16 bits
xchg 2[BP],BX ; - ...
xchg 4[BP],BX ; - ...
sub DX,16 ; - decrement exponent by 16
_endloop ; endloop
_loop ; loop (normalize it)
or BX,BX ; - check for implied 1 bit
_quif s ; - quit if its on
shl word ptr [BP],1 ; - shift fraction left
rcl word ptr 2[BP],1; - ...
rcl word ptr 4[BP],1; - ...
_rcl BX,1 ; - ...
dec DX ; - decrement exponent
_endloop ; endloop
mov 6[BP],BX ; save high order word
xchg DI,BP ; restore address of operand
ret ; return
normalize_opnd endp
ifdef _BUILDING_MATHLIB
endmod
endf equ end
else
endf equ <>
endif
endf
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?