fldd386.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 392 行 · 第 1/2 页
ASM
392 行
ret ; - - return 0
_endif ; - endif
rcr SI,1 ; - put back the sign
_endguess ; endguess
push EBP ; save EBP
mov EBP,ESP ; get access to stack
push EDI ; save EDI
xchg ECX,ESI ; get exponents and signs into ECX
mov EDI,ECX ; get exponent and sign of op1 into EDI
rol EDI,16 ; shift to top
sar EDI,16 ; shift exponent to bottom, duplicating sign
sar ECX,16 ; shift exponent to bottom, duplicating sign
and EDI,80007FFFh ; isolate signs and exponent
and ECX,80007FFFh ; ...
rol EDI,16 ; rotate signs to bottom
rol ECX,16 ; ...
add DI,CX ; calc sign of result
rol EDI,16 ; rotate signs to top
rol ECX,16 ; ...
or DI,DI ; if op1 is a denormal
_if e ; then
_loop ; - loop (normalize it)
_shl EAX,1 ; - - shift fraction left
_rcl EDX,1 ; - - . . .
dec DI ; - - decrement exponent
or EDX,EDX ; - - check for implied 1 bit
_until s ; - until implied 1 bit is on
_endif ; endif
or CX,CX ; if op2 is a denormal
_if e ; then
_loop ; - loop (normalize it)
_shl EBX,1 ; - - shift fraction left
_rcl ESI,1 ; - - . . .
dec CX ; - - decrement exponent
or ESI,ESI ; - - check for implied 1 bit
_until s ; - until implied 1 bit is on
_endif ; endif
sub DI,CX ; calculate exponent of result
add DI,3FFFh ; add in removed bias
_guess ; guess: overflow
_quif s ; - quit if exponent is negative
cmp DI,7FFFh ; - quit if not overflow
_quif b ; - . . .
mov EDI,ECX ; - get sign
mov DI,7FFFh ; - set infinity
mov EDX,80000000h ; - ...
sub EAX,EAX ; - ...
jmp _divret ; - return (infinity)
_endguess ; endguess
cmp DI,-64 ; if exponent is too small
_if l ; then underflow
sub EAX,EAX ; - set result to 0
sub EDX,EDX ; - ...
sub EDI,EDI ; - ...
jmp _divret ; - return (underflow)
_endif ; endif
push EDI ; save sign and exponent
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,EDI ; 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
;;
;; _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
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
_divret:
_shl EDI,1 ; get sign
rcr DI,1 ; merge it with exponent
mov ESI,EDI ; get exponent and sign into SI
pop EDI ; ...
pop EBP ; ...
ret ; return
endproc ___LDD
ifdef _BUILDING_MATHLIB
endmod
endf equ end
else
endf equ <>
endif
endf
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?