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
		
			
				
	
	
		
			150 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			NASM
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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
 |