div386.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 308 行 · 第 1/2 页
ASM
308 行
pop ESI ; - restore ESI
pop EDI ; - restore EDI
pop EBP ; - restore EBP
jmp F8OverFlow ; - handle overflow
_endguess ; endguess
cmp DI,-52 ; if exponent is too small
_if l ; then underflow
pop ESI ; - restore ESI
pop EDI ; - restore EDI
pop EBP ; - restore EBP
jmp F8UnderFlow ; - handle underflow
_endif ; endif
push EDI ; save sign and exponent
mov CL,11 ; shift fractions to top of registers
shld EDX,EAX,CL ; ...
shld EAX,EBP,CL ; ...
and EAX,0FFFFF800h ; ...
shld ESI,EBX,CL ; ...
shld EBX,EBP,CL ; ...
and EBX,0FFFFF800h ; ...
push ESI ; save divisor
push EBX ; ...
mov ECX,ESI ; get top part of divisor
mov EDI,EDX ; get dividend
mov ESI,EAX ; ...
sub EAX,EAX ; assume top bit is 0
cmp ECX,EDX ; check high parts
_if be ; if hi(divisor) <= hi(dividend)
sub EDX,ECX ; - subtract divisor from dividend
inc EAX ; - set quotient to 1
_endif ; endif
push EAX ; save high word of quotient
mov EAX,ESI ; get low part of dividend
div ECX ; estimate next word of quotient
push EAX ; save estimate of quotient (quot+4[EBP])
xchg EAX,EBX ; save quot., get low word of divisor
mul EBX ; calc. estimate * lo(divisor)
xchg EAX,ECX ; ...
xchg EBX,EDX ; save partial product
mul EDX ; calc. estimate * hi(divisor)
add EAX,EBX ; add to partial product
adc EDX,0 ; ...
mov EBX,den+lo[EBP] ; get low word of divisor
test byte ptr quot+8[EBP],1 ; if high word of quot is 1
_if ne ; then
add EAX,EBX ; - add in divisor
adc EDX,den+hi[EBP] ; - ...
_endif ; endif
; subtract estimate * divisor from dividend
neg ECX ; 0 - ECX
sbb ESI,EAX ; ...
sbb EDI,EDX ; ...
_if ne ; if high word not 0 (quotient too big)
_loop ; - loop (find correct quotient)
sub dword ptr quot+4[EBP],1; - - decrement quotient
sbb dword ptr quot+8[EBP],0; - - ...
add ECX,EBX ; - - add divisor back to dividend
adc ESI,den+hi[EBP] ; - - ...
adc EDI,0 ; - - ...
_until e ; - until done
_endif ; endif
mov EDI,ESI ; get new dividend
mov ESI,ECX ; ...
mov ECX,den+hi[EBP] ; get divisor
cmp ECX,EDI ; check high parts 13-aug-90
_if be ; if hi(divisor) <= hi(dividend)
sub EDI,ECX ; - subtract divisor from dividend
add dword ptr quot+4[EBP],1 ; - increment quotient
adc dword ptr quot+8[EBP],0 ; - ...
_endif ; endif
mov EDX,EDI ; get dividend into EDX:EAX
mov EAX,ESI ; ...
div ECX ; estimate next word of quotient
push EAX ; save estimate of quotient (-4[EBP])
or EAX,EAX ; if quotient non-zero
_if ne ; then
xchg EAX,EBX ; - save quot., get low word of divisor
mul EBX ; - calc. estimate * lo(divisor)
xchg EAX,ECX ; - ...
xchg EBX,EDX ; - save partial product
mul EDX ; - calc. estimate * hi(divisor)
add EAX,EBX ; - add to partial product
adc EDX,0 ; - ...
; - subtract estimate * divisor from dividend
neg ECX ; - 0 - ECX
sbb ESI,EAX ; - ...
sbb EDI,EDX ; - ...
_if ne ; - if high word not 0 (quotient too big)
_loop ; - - loop (find correct quotient)
sub dword ptr quot+0[EBP],1; - - - decrement quotient
sbb dword ptr quot+4[EBP],0; - - - ...
sbb dword ptr quot+8[EBP],0; - - - ...
add ECX,den+lo[EBP] ; - - - add divisor back to dividend
adc ESI,den+hi[EBP] ; - - - ...
adc EDI,0 ; - - - ...
_until e ; - - until done
_endif ; - endif
_endif ; endif
pop EAX ; get quotient
pop EDX ; ...
pop EBX ; get high bit
add ESP,8 ; remove divisor
pop EDI ; restore sign and exponent
dec DI ; decrement exponent
shr EBX,1 ; if non-zero
_if c ; then
rcr EDX,1 ; - shift answer right
rcr EAX,1 ; - ...
inc EDI ; - increment exponent
_endif ; endif
sub ESI,ESI ; get zero for zero fill
mov CL,11 ; shift result over
shrd EAX,EDX,CL ; ...
rcr ESI,1 ; save carry
shrd EDX,ESI,CL ; ...
or EDX,0FFF00000h ; turn top bits all on
_shl ESI,1 ; get guard bit
adc EAX,0 ; round up
adc EDX,0 ; ...
adc EDI,0 ; increment exponent if required
or DI,DI ; if exponent <= 0
_if le ; then (denormal result)
_if e ; - if exponent = 0
mov CL,1 ; - - set shift count to 1
_else ; - else
neg DI ; - - negate to get shift count
mov CX,DI ; - - ...
_endif ; - endif
and EDX,001FFFFFh ; - isolate fraction
sub EBX,EBX ; - for zero fill
shrd EAX,EDX,CL ; - align the fraction
shrd EDX,EBX,CL ; - ...
sub DI,DI ; - set exponent to 0
_endif ; endif
and EDX,000FFFFFh ; isolate fraction
mov ESI,EDI ; get copy of sign
ror EDI,11 ; get exponent
_shl ESI,1 ; get sign
rcr EDI,1 ; put it in
and EDI,0FFF00000h ; isolate sign and exponent
or EDX,EDI ; place it in result
pop ESI ; restore registers
pop EDI ; ...
pop EBP ; ...
ret ; return
endproc __FDD
endmod
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?