Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll) git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
190 lines
4.0 KiB
NASM
Executable File
190 lines
4.0 KiB
NASM
Executable File
; int _MulUnsArrByPwrOf10Limited(pa, n, dig);
|
|
;
|
|
;
|
|
; ARGUMENTS
|
|
; unsigned *pa[] points to pa[10], a 160 bit number
|
|
; (both input and output)
|
|
; int n Number of power of ten multiplier 0..19
|
|
; int dig Number of digits to multiply
|
|
;
|
|
; DESCRIPTION
|
|
; Multiplies the input in the pa[] array (a 160-bit binary number)
|
|
; by 10^n where 0<=n<=19.
|
|
; If multiplication overflows, multiplies by largest power of 10
|
|
; which doesn't overflow and returns that power of ten.
|
|
; The application is in addition when lining up decimal points.
|
|
;
|
|
; SIDE EFFECTS
|
|
; None. (always succeeds)
|
|
;
|
|
; RETURNS
|
|
; Power of ten multiplied by, always <= n.
|
|
;
|
|
;
|
|
; AUTHOR
|
|
; Don Killen 14-Jun-1988 15:19:03
|
|
; Copyright (C) 1988-90 Greenleaf Software Inc. All Rights Reserved.
|
|
;
|
|
include model.h
|
|
include prologue.h
|
|
include gm.equ
|
|
|
|
dseg mul10l
|
|
power dw 1 dup(?) ; power of ten to do
|
|
numdig dw 1 dup(?) ; number of nonzero digits
|
|
work dw 12 dup (?) ; intermediate result array
|
|
hiword dw 1 dup(?) ; byte # of highest word
|
|
endds
|
|
|
|
pseg mul10l
|
|
cproc _MulUnsArrByPwrOf10Limited,,_mul10l
|
|
if _LDATA
|
|
push es
|
|
les di,parm1_ ; get pointer to source/destination
|
|
mov ax,parm3_ ; get power of 10
|
|
mov bx,parm4_ ; get number of digits
|
|
else
|
|
mov di,parm1_ ; get pointer to source/destination
|
|
mov ax,ds
|
|
mov es,ax
|
|
mov ax,parm2_ ; get power of 10
|
|
mov bx,parm3_ ; get number of digits
|
|
endif
|
|
|
|
mov numdig,bx ; store the number of digits
|
|
mov power,ax ; store power of 10
|
|
shl bx, 1 ; bytes rather than words
|
|
mov dx, bx
|
|
dec dx ; highest byte # is two less than # of bytes
|
|
dec dx
|
|
mov hiword, dx ; store location of highest word
|
|
|
|
;
|
|
; Strategy is to multiply by shifting left all 160 bits.
|
|
;
|
|
; a) Move (parm1) -> work array
|
|
; b) shift left work array twice, multiplying by 4
|
|
; c) Add (parm1) <= (parm1)+work, multiplying by 5
|
|
; d) Shift (parm1) left once, multiplying by 10
|
|
; e) Test for overflow (carry out of MSW) each step (jmp to error)
|
|
; f) If no error, decrement power & loop to (a) if nonzero.
|
|
; g) When power has been decremented to 0, you're done!
|
|
;
|
|
|
|
;
|
|
; Top of main loop, repeat from here 'power' times.
|
|
;
|
|
lp0: ; top of major loop.
|
|
;
|
|
; Transfer the source to the work array. Work from msd down to lsd
|
|
;
|
|
if _LDATA
|
|
les di,parm1_
|
|
else
|
|
mov di,parm1_
|
|
endif
|
|
|
|
mov ax, 3276d ; if high word >= 3276,
|
|
mov bx, hiword ; can't multiply any more
|
|
cmp ax, word ptr es:[di+bx]
|
|
jg canmul ; can multiply
|
|
|
|
if _LDATA ; No more mul's possible
|
|
mov ax, parm3_ ; From total multiplications,
|
|
else
|
|
mov ax, parm2_
|
|
endif
|
|
sub ax, power ; Subtract remaining mul's
|
|
jmp short overflow ; to return number of mul's
|
|
|
|
canmul:
|
|
mov si,0 ; move msd first
|
|
mov cx,numdig
|
|
lp2: mov ax,word ptr es:[di] ; load source word
|
|
mov word ptr work[si],ax ; store in 'work'
|
|
inc si
|
|
inc si
|
|
inc di
|
|
inc di
|
|
loop lp2 ; til done.
|
|
;
|
|
; Shift the work array left two bits.
|
|
;
|
|
mov cx,numdig ; loop count
|
|
mov si,0 ; index into work array
|
|
clc
|
|
lp4: rcl word ptr work[si],1 ; rotate with carry
|
|
inc si
|
|
inc si
|
|
loop lp4 ; complete 1st shift (x2)
|
|
|
|
mov cx,numdig
|
|
mov si,0
|
|
clc
|
|
lp5: rcl word ptr work[si],1 ; rotate with carry
|
|
inc si
|
|
inc si
|
|
loop lp5 ; complete 2nd shift (x4)
|
|
;
|
|
; So far, work=pa*4.
|
|
;
|
|
; Add pa=pa+work, making pa=pa*5
|
|
;
|
|
if _LDATA
|
|
les di,parm1_ ; get pointer to source/destination
|
|
else
|
|
mov di,parm1_ ; get pointer to source/destination
|
|
endif
|
|
|
|
mov cx,numdig
|
|
mov si,0
|
|
clc
|
|
lp6: mov ax,word ptr work[si]
|
|
adc word ptr es:[di],ax
|
|
inc di
|
|
inc di
|
|
inc si
|
|
inc si
|
|
loop lp6 ; Added orig array to 4x: (x5)
|
|
;
|
|
;
|
|
; At this point, pa=pa*5. Now shift it left making pa=pa*10
|
|
;
|
|
if _LDATA
|
|
les di,parm1_
|
|
else
|
|
mov di,parm1_
|
|
endif
|
|
mov cx,numdig
|
|
clc
|
|
lp7: rcl word ptr es:[di],1 ; rotate left to shift with carry.
|
|
inc di
|
|
inc di
|
|
loop lp7 ; Multiplied (x5) by 2 making (x10) in src
|
|
|
|
; Code deleted 1/15/90 MRN
|
|
;
|
|
; If no overflow has occurred, decrement power counter and loop
|
|
; through entire x10 routine.
|
|
;
|
|
|
|
dpow: dec power
|
|
jz mcomplete
|
|
jmp lp0 ; major loop
|
|
|
|
mcomplete:
|
|
if _LDATA
|
|
mov ax, parm3_ ; did all requested multiplications
|
|
else
|
|
mov ax, parm2_
|
|
endif
|
|
|
|
overflow:
|
|
if _LDATA
|
|
pop es
|
|
endif
|
|
cproce
|
|
|
|
endps
|
|
end
|