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
 |