campo-sirio/gfm/mul10.asm
alex ba237a9d91 Patch level : no patch
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
2002-02-26 12:19:02 +00:00

150 lines
3.7 KiB
NASM
Executable File

; int _MulUnsArrByPwrOf10(pa,n,w);
;
;
; ARGUMENTS
; unsigned *pa[] points to pa[10], a w word number
; (both input and output)
; int n Number of power of ten multiplier 0..47
; int w Number of words (digits)
;
; DESCRIPTION
; Multiplies the input in the pa[] array (a w word number)
; by 10^n where 0<=n<=47.
;
; The application is in divide routines for adjusting the result.
;
; SIDE EFFECTS
; The value in the source array is unchanged on overflow.
;
; RETURNS
; GM_OVERFLOW if there is an overflow, otherwise GM_SUCCESS.
;
;
; 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 mul10
power dw 1 dup(?) ; power of ten to do
numnz dw 1 dup(?) ; number of nonzero digits
totdig dw 1 dup(?) ; total number of digits
tmpdig dw 1 dup(?) ; temp. copy of number of non-zero digits
p10 dw 1,10d,100d,1000d,10000d ; powers of 10
endds
pseg mul10
cproc _MulUnsArrByPwrOf10,,_mul10
if _LDATA
push es
les di,parm1_ ; get pointer to source/destination
mov dx,parm3_ ; get power of 10
mov bx,parm4_ ; get number of words
else
mov di,parm1_ ; get pointer to source/destination
mov ax,ds
mov es,ax
mov dx,parm2_ ; get power of 10
mov bx,parm3_ ; get number of words
endif
mov si, di ; copy array location (for future recall)
mov totdig, bx ; store number of digits
; dec power
; Find highest nonzero digit
; (so time isn't wasted multiplying zeroes)
sal bx, 1 ; want digits in words
lpnz: dec bx ; decrease word by 1 (2 bytes)
dec bx
jns nxtlin
jmp success ; negative bx => source is 0 => done
nxtlin: mov ax,0
cmp ax,word ptr es:[di+bx]
je lpnz
;
shr bx,1 ; want number of words, not bytes
inc bx ; number of digits one more than digit number
mov numnz,bx ; store # of non-zero digits
mov tmpdig,bx ; store again (for counter)
; multiplies by 10000 for all multiplications but last to run faster
; find correct number to mul by & decrease power (# of remaining muls)
bigloop:
cmp dx, 4 ; check if multiplying by power greater than 4
jge pg4
mov ax, 0 ; if so, no subsequent muls needed
mov power, ax
sal dx, 1 ; get power of 10
mov bx, dx
mov bx, p10[bx]
jmp short bmul
pg4:
sub dx, 4 ; subtract 4 from remaining powers of 10
mov power, dx
mov bx, 10000d
; begin multiplication, handling first digit specially
bmul:
mov ax, word ptr es:[di] ; get first digit
mul bx ; multiply digit
mov word ptr es:[di], ax ; store lower digit
dec tmpdig ; decrease digit counter
clc
jz onedig ; only one digit
; now multiply remaining digits
loop1:
mov cx, dx ; save high word
inc di ; go to next digit
inc di
mov ax, word ptr es:[di] ; get next digit
pushf ; save carry flag
mul bx ; multiply digit
popf ; retrieve carry flag
adc ax, cx ; add previous high word
mov word ptr es:[di], ax ; store lower digit
dec tmpdig ; check if any more digs to mul
jnz loop1
; handle carry into additional digit (contained in dx)
onedig:
adc dx, 0 ; add carry flag
jz nomore ; if dx=0, no more nonzero digits
; if additional digit, increment digit # & store digit
mov ax, numnz ; get old # of digits
cmp ax, totdig ; check for overflow
jge overflow ; if equal, overflow occured
inc numnz ; one more digit now
inc di ; digit goes in next word
inc di
mov word ptr es:[di], dx ; store high digit
nomore:
mov dx, power ; check if through
cmp dx, 0
jz success
mov ax, numnz ; get # of digits
mov tmpdig,ax ; copy # of non-zero digits
mov di, si ; copy pointer
jmp short bigloop
overflow:
mov ax,GM_OVERFLOW ; indicate error
jmp short through
success:
mov ax,GM_SUCCESS
through:
if _LDATA
pop es
endif
cproce
endps
end