fldm086.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 439 行 · 第 1/2 页
ASM
439 行
_quif ne ; - ...
dec BX ; - decrement counter
or CX,4[DI] ; - ...
_quif ne ; - ...
dec BX ; - decrement counter
or CX,6[DI] ; - ...
; if CX = 8000h, then op2 is a power of 2, just return op1 with
; appropriate sign and exponent
xchg SI,DI ; - flip pointers
cmp CX,8000h ; - if op2 is a power of 2
je pow2_hop ; - then do special calc.
xchg SI,DI ; - flip pointers back
or CX,CX ; - test high order word
_quif ne ; - quit if op2 is not 0
test DX,7FFFh ; - quit if exponent is not 0
_quif ne ; - ...
mov AX,CX ; - set result to 0
mov BX,CX ; - ...
mov DX,CX ; - ...
mov SI,CX ; - ...
ifdef _BUILDING_MATHLIB
pop DS ; - restore DS
endif
ret ; - return 0
_endguess ; endguess
or BX,BX ; if op2 has more lower word zeros than op1
_if s ; then
xchg SI,DI ; - flip the arguments to reduce # of multiplies
_endif ; endif
mov CX,AX ; calc. sign of result
xor CX,DX ; ...
and CX,8000h ; ...
and AH,7Fh ; isolate exponent
and DH,7Fh ; ...
_guess ; guess: overflow
add AX,DX ; - determine exponent of result
sub AX,3FFEh ; - remove extra bias
cmp AX,-3FFEh ; - quit if exponent is negative
_quif ae ; - . . .
cmp AX,7FFFh ; - quit if not overflow
_quif b ; - . . .
jmp mul_oflow ; - handle overflow
_endguess ; endguess
cmp AX,-64 ; if exponent is too small
_if l ; then underflow
sub AX,AX ; - set result to 0
mov BX,AX ; - ...
mov CX,AX ; - ...
mov DX,AX ; - ...
mov SI,AX ; - ...
ifdef _BUILDING_MATHLIB
pop DS ; - restore DS
endif
ret ; - return
_endif ; endif
push BP ; save BP
push CX ; save sign of result
push AX ; save exponent
sub BX,BX ; zero BX
push BX ; allocate and zero accumulator
push BX ; ...
push BX ; ...
push BX ; ...
push BX ; ...
push BX ; ...
push BX ; ...
push BX ; ... (sticky bits)
push 6[DI] ; push multiplicand onto stack
push 4[DI] ; ...
push 2[DI] ; ...
push [DI] ; ...
mov BP,SP ; point to multiplicand and accumulator
push 6[SI] ; push multiplier onto stack
push 4[SI] ; ...
push 2[SI] ; ...
push [SI] ; ...
_loop ; loop (until SP=BP)
pop SI ; - get next word of multiplier from stack
mov BX,SP ; - get access to stack
mov DI,SS:14+0[BX] ; - get low order word for sticky bits
or SI,SI ; - if multiplier not zero
_if ne ; - then
sub CX,CX ; - - zero CX
mov AX,[BP] ; - - get low order word of multiplicand
mul SI ; - - do multiply
mov DI,AX ; - - save result
mov BX,DX ; - - ...
mov AX,2[BP] ; - - get next word of multiplicand
mul SI ; - - do multiply
add BX,AX ; - - accumulate result
adc CX,DX ; - - ...
mov AX,4[BP] ; - - get next word of multiplicand
mul SI ; - - do multiply
add CX,AX ; - - accumulate result
adc DX,0 ; - - ...
xchg DX,SI ; - - answer in SI, multiplier in DX
mov AX,6[BP] ; - - get last word of multiplicand
mul DX ; - - do multiply
add AX,SI ; - - accumulate result
adc DX,0 ; - - ...
mov SI,BP ; - - save BP
mov BP,SP ; - - get access to stack
add DI,14+0[BP] ; - - accumulate result
adc 14+2[BP],BX ; - - ...
adc 14+4[BP],CX ; - - ...
adc 14+6[BP],AX ; - - ...
adc 14+8[BP],DX ; - - ...
mov BP,SI ; - - restore BP
_endif ; - endif
or 8[BP],DI ; - update the sticky bits
cmp SP,BP ; - check to see if we are done
_until e ; until done
donemul:
mov DI,14+0[BP] ; get result
mov DX,14+2[BP] ; ...
mov CX,14+4[BP] ; ...
mov BX,14+6[BP] ; ...
mov AX,14+8[BP] ; ...
;
; now have AX:BX:CX:DX:DI containing the fraction
;
mov BP,8[BP] ; get sticky bits
add SP,8+(8*2) ; clean up the stack
pop SI ; get exponent
_guess ; guess: exponent >= 0
or SI,SI ; - quit if exponent < 0
_quif s ; - ...
_loop ; - loop (normalize)
_shl DI,1 ; - - shift number left 1
_rcl DX,1 ; - - ...
_rcl CX,1 ; - - ...
_rcl BX,1 ; - - ...
_rcl AX,1 ; - - ...
dec SI ; - - decrement exponent (doesn't change carry)
_quif s ; - - exit if denormal operand
_until c ; - until carry
inc SI ; - bump exponent back up one
_if e ; - if exponent is 0
_if nc ; - - if no carry from fraction
; cmp AX,7FFFh ; - - - and fraction < 8000h
; _if le ; - - - then
; cmp SP,SI ; - - - - cmp things that aren't equal
; _endif ; - - - endif
_endif ; - - endif
_endif ; - endif
_quif e ; - exit if denormal operand
_admit ; admit: exponent <= 0
_loop ; - loop (number is a denormal)
shr AX,1 ; - - shift number right
rcr BX,1 ; - - ...
rcr CX,1 ; - - ...
rcr DX,1 ; - - ...
adc BP,0 ; - - add carry to sticky bits
inc SI ; - - increment exponent
_until ns ; - until back to 0
clc ; - clear carry
_endguess ; endguess
rcr AX,1 ; shift fraction right once
rcr BX,1 ; ...
rcr CX,1 ; ...
rcr DX,1 ; ...
_if c ; if guard bit is on
or BP,BP ; - if no sticky bits
_if e ; - then
or SI,SI ; - - if exponent not 0
_if ne ; - - then
mov BP,DX ; - - - get low order word
shr BP,1 ; - - - get bottom bit
cmc ; - - - complement it
_endif ; - - endif
_endif ; - endif
cmc ; - complement carry
adc DX,0 ; - round up
adc CX,0 ; - ...
adc BX,0 ; - ...
adc AX,0 ; - ...
_if c ; - if carry 05-jul-90
inc SI ; - - increment exponent
mov AH,80h ; - - set fraction
_endif ; - endif
_endif ; endif
pop BP ; restore sign
or SI,BP ; merge sign in with exponent
pop BP ; restore BP
ifdef _BUILDING_MATHLIB
pop DS ; restore DS
endif
ret ; return
mul_denormal:
pop SI ; restore sign
pop BP ; restore BP
ifdef _BUILDING_MATHLIB
pop DS ; restore DS
endif
ret ; return
endproc ___LDM
ifdef _BUILDING_MATHLIB
endmod
endf equ end
else
endf equ <>
endif
endf
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?