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
 |