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
		
			
				
	
	
		
			327 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			NASM
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			NASM
		
	
	
		
			Executable File
		
	
	
	
	
 ; void _DivUnsArrByUnsArr(c, a, m, b, n, rf)
 | 
						|
 ;
 | 
						|
 ; ARGUMENT
 | 
						|
 ;      unsigned        a[], b[], c[];
 | 
						|
 ;      int             m, n;
 | 
						|
 ;      int             rf;
 | 
						|
 ;
 | 
						|
 ; DESCRIPTION
 | 
						|
 ;      Divides an m-word integer a by an n-integer word b, storing the result
 | 
						|
 ; in c.  a and b must both be positive, and m >= n.  The quotient is
 | 
						|
 ; rounded when rf is set, otherwise is it truncated.
 | 
						|
 ;
 | 
						|
 ; SIDE EFFECTS
 | 
						|
 ;      None.
 | 
						|
 ;
 | 
						|
 ; RETURNS
 | 
						|
 ;      None.
 | 
						|
 ;
 | 
						|
 ; AUTHOR
 | 
						|
 ;  Jared Levy  7/9/89
 | 
						|
 ;   Copyright (C) 1989-90 Greenleaf Software Inc.  All Rights Reserved.
 | 
						|
 ;
 | 
						|
 ; MODIFICATIONS
 | 
						|
 ;
 | 
						|
 ;
 | 
						|
 ;
 | 
						|
	include model.h
 | 
						|
	include prologue.h
 | 
						|
	include gm.equ
 | 
						|
 | 
						|
	dseg    dmbyn
 | 
						|
acopm2  dw      1 dup(?)
 | 
						|
acop    dw      12 dup(?)
 | 
						|
diga    dw      1 dup(?)
 | 
						|
bcopm2  dw      1 dup(?)
 | 
						|
bcop    dw      6 dup(?)
 | 
						|
digb    dw      1 dup(?)
 | 
						|
digb2   dw      1 dup(?)
 | 
						|
digbp1  dw      1 dup(?)
 | 
						|
numquot dw      1 dup(?)
 | 
						|
firstb  dw      1 dup(?)
 | 
						|
dstplc  dw      1 dup(?)
 | 
						|
partpr  dw      6 dup (?)
 | 
						|
quotdig dw      1 dup(?)
 | 
						|
	endds
 | 
						|
 | 
						|
	pseg    dmbyn
 | 
						|
	cproc   _DivUnsArrByUnsArr,,_dmbyn
 | 
						|
 | 
						|
; load parameters
 | 
						|
if      _LDATA
 | 
						|
	push    es
 | 
						|
	les     si, parm6_      ; get source pointer b
 | 
						|
	mov     bx, parm8_      ; get # of digits in b
 | 
						|
else
 | 
						|
	mov     ax, ds
 | 
						|
	mov     es, ax
 | 
						|
	mov     si, parm4_      ; get source pointer b
 | 
						|
	mov     bx, parm5_      ; get # of digits in b
 | 
						|
endif
 | 
						|
 | 
						|
; copy b
 | 
						|
	mov     digb, bx        ; store # digits of b
 | 
						|
	mov     digbp1, bx
 | 
						|
	inc     digbp1          ; store 1 + # digits of b
 | 
						|
	sal     bx, 1
 | 
						|
	mov     digb2, bx               ; store twice # digits of b
 | 
						|
 | 
						|
	mov     word ptr bcop[bx], 0    ; store 0 in extra word
 | 
						|
loopcb:
 | 
						|
	dec     bx                      ; next word
 | 
						|
	dec     bx
 | 
						|
	mov     ax, word ptr es:[si+bx] ; copy element of b
 | 
						|
	mov     word ptr bcop[bx], ax
 | 
						|
	jnz     loopcb
 | 
						|
 | 
						|
if      _LDATA
 | 
						|
	les     si, parm3_      ; get source pointer a
 | 
						|
	mov     bx, parm5_      ; get # of digits in a
 | 
						|
else
 | 
						|
	mov     si, parm2_      ; get source pointer a
 | 
						|
	mov     bx, parm3_      ; get # of digits in a
 | 
						|
endif
 | 
						|
 | 
						|
; copy a
 | 
						|
	mov     diga, bx        ; store # digits of a
 | 
						|
	sal     bx, 1
 | 
						|
	xor     ax, ax
 | 
						|
	mov     acop[bx], ax    ; store zero in extra word
 | 
						|
loopca:
 | 
						|
	dec     bx                      ; next word
 | 
						|
	dec     bx
 | 
						|
	mov     ax, word ptr es:[si+bx] ; copy element of a
 | 
						|
	mov     word ptr acop[bx], ax
 | 
						|
	jnz     loopca
 | 
						|
 | 
						|
; rotate b and a left until high bit of b is set
 | 
						|
	mov     bx, digb2
 | 
						|
	mov     ax, bcopm2[bx]          ; get high word of b
 | 
						|
	mov     firstb, ax
 | 
						|
	rcl     ax,1                    ; see if high bit set
 | 
						|
	jc      noshift
 | 
						|
 | 
						|
	xor     dx,dx
 | 
						|
shwb:
 | 
						|
	xor     bx,bx                   ; start shifting at low digit
 | 
						|
	mov     cx,digb
 | 
						|
	clc
 | 
						|
shblp:
 | 
						|
	rcl     bcop[bx],1              ; rotate digit left
 | 
						|
	inc     bx                      ; next digit
 | 
						|
	inc     bx
 | 
						|
	loop    shblp
 | 
						|
 | 
						|
	inc     dx                      ; keep track of # of shifts
 | 
						|
	mov     ax, bcopm2[bx]          ; get high word of b
 | 
						|
	rcl     ax,1                    ; see if high bit set
 | 
						|
	jnc     shwb
 | 
						|
	mov     ax, bcopm2[bx]          ; get first digit of b
 | 
						|
	mov     firstb, ax              ;  & store
 | 
						|
 | 
						|
shwa:
 | 
						|
	xor     bx,bx                   ; start shifting at low digit
 | 
						|
	mov     cx,diga
 | 
						|
	inc     cx                      ; shift extra digit of a
 | 
						|
	clc
 | 
						|
shalp:
 | 
						|
	rcl     acop[bx],1              ; rotate digit left
 | 
						|
	inc     bx                      ; next digit
 | 
						|
	inc     bx
 | 
						|
	loop    shalp
 | 
						|
 | 
						|
	dec     dx
 | 
						|
	jnz     shwa
 | 
						|
 | 
						|
noshift:
 | 
						|
;       set up source and destination pointers
 | 
						|
if      _LDATA
 | 
						|
	les     di, parm1_      ; get destination pointer c
 | 
						|
else
 | 
						|
	mov     di, parm1_      ; get destination pointer c
 | 
						|
endif
 | 
						|
; zero destination
 | 
						|
	mov     bx, 8d
 | 
						|
	xor     ax, ax
 | 
						|
zerocl:
 | 
						|
	mov     word ptr es:[di+bx], ax
 | 
						|
	dec     bx
 | 
						|
	dec     bx
 | 
						|
	jns     zerocl
 | 
						|
 | 
						|
	mov     ax, diga        ; find location to store digits
 | 
						|
	sub     ax, digb        ; highest digit stored in word # diga - digb
 | 
						|
	jns     nxtline         ; if b has more digits than a, done
 | 
						|
	jmp     done
 | 
						|
nxtline:
 | 
						|
	mov     numquot, ax
 | 
						|
	inc     numquot         ; compute number of quotient digits
 | 
						|
	sal     ax, 1
 | 
						|
	add     di, ax          ; where highest quotient digit stored
 | 
						|
	mov     dstplc, di
 | 
						|
 | 
						|
	mov     di, ax          ; place to begin first subtraction
 | 
						|
	mov     ax, diga
 | 
						|
	sal     ax, 1
 | 
						|
	mov     si, ax          ; place to begin first compare
 | 
						|
 | 
						|
; if first digit of b is larger than first digit of a,
 | 
						|
;    first digit of quotient is 0
 | 
						|
	mov     ax, 0
 | 
						|
	cmp     ax, acop[si]
 | 
						|
	jne     firstn0
 | 
						|
	mov     ax, firstb      ; get high digit of b
 | 
						|
	cmp     ax, acopm2[si]  ; compare to high digit of a
 | 
						|
	jbe     firstn0         ; first quot. digit non-zero
 | 
						|
 | 
						|
	dec     numquot         ; otherwise, one less quotient digit
 | 
						|
	jnz     nline2          ; if a<b, division done
 | 
						|
	jmp     done
 | 
						|
nline2:
 | 
						|
	jns     wordloop
 | 
						|
	jmp     done
 | 
						|
 | 
						|
wordloop:
 | 
						|
	dec     di              ; look at lower digits of a
 | 
						|
	dec     di
 | 
						|
	dec     si              ; decrease desination pointer
 | 
						|
	dec     si
 | 
						|
	dec     dstplc
 | 
						|
	dec     dstplc
 | 
						|
 | 
						|
firstn0:
 | 
						|
; finally divide
 | 
						|
 | 
						|
; divide first digit of b into first two of a
 | 
						|
	mov     dx, acop[si]    ; get top 2 remaining words of a
 | 
						|
	mov     ax, 65535d
 | 
						|
	cmp     dx, firstb      ; check if first digits of a & b same
 | 
						|
	je      f65535          ; if so, quotient is 65535
 | 
						|
	mov     ax, acopm2[si]
 | 
						|
	div     word ptr firstb ; divide by first digit of b
 | 
						|
f65535:
 | 
						|
	mov     quotdig, ax     ; store quotient
 | 
						|
 | 
						|
; multiply b by quotient
 | 
						|
; first digit
 | 
						|
	mul     word ptr bcop   ; mul low digit
 | 
						|
	mov     partpr, ax      ; store partial product
 | 
						|
	mov     bx, 2           ; now second word
 | 
						|
	clc
 | 
						|
	pushf                   ; save carry flag
 | 
						|
; middle digits
 | 
						|
mullp:
 | 
						|
	mov     cx, dx          ; save high word from last mul
 | 
						|
	mov     ax, quotdig     ; get quotient
 | 
						|
	mul     bcop[bx]        ; mul digit
 | 
						|
	popf                    ; restore carry flag
 | 
						|
	adc     ax, cx          ; add high word from last mul
 | 
						|
	pushf                   ; save carry flag
 | 
						|
	mov     partpr[bx], ax  ; store partial product digit
 | 
						|
	inc     bx              ; next digit
 | 
						|
	inc     bx
 | 
						|
	cmp     bx, digb2       ; check if done
 | 
						|
	jl      mullp
 | 
						|
; last digit
 | 
						|
	xor     ax, ax          ; high digit
 | 
						|
	popf                    ; restore carry flag
 | 
						|
	adc     ax, dx          ; add carry flag
 | 
						|
	mov     partpr[bx], ax  ; store high digit
 | 
						|
 | 
						|
; compare partial product to a
 | 
						|
cmplp:
 | 
						|
	mov     ax, word ptr partpr[bx] ; get high word of b
 | 
						|
	cmp     ax, word ptr acop[di+bx]        ; compare to high word of a
 | 
						|
	jb      worksout                ; if b * q < a, quotient right
 | 
						|
	ja      toolarge                ; if b * q > a, quotient too big
 | 
						|
	dec     bx                      ; if equal compare next digit
 | 
						|
	dec     bx
 | 
						|
	jns     cmplp           ; if b=a, compare remaining digits
 | 
						|
	jmp     short worksout          ; if exactly equal quotient right
 | 
						|
 | 
						|
toolarge:
 | 
						|
; when quotient too large, decrease quotient & adjust partial product
 | 
						|
	dec     quotdig                 ; lower quotient by 1
 | 
						|
	mov     bx, 0                   ; subtract b from partial prod.
 | 
						|
	clc
 | 
						|
	mov     cx, digbp1
 | 
						|
subtllp:
 | 
						|
	mov     ax, bcop[bx]            ; get dig of b
 | 
						|
	sbb     partpr[bx], ax          ; subtract from partial prod.
 | 
						|
	inc     bx                      ; next digit
 | 
						|
	inc     bx
 | 
						|
	loop    subtllp
 | 
						|
	dec     bx                      ; bx must have right value for cmp
 | 
						|
	dec     bx
 | 
						|
	jmp     short cmplp
 | 
						|
 | 
						|
worksout:
 | 
						|
; store quotient digit
 | 
						|
	mov     bx, dstplc
 | 
						|
	mov     ax, quotdig
 | 
						|
	mov     es:[bx], ax
 | 
						|
 | 
						|
; subtract number
 | 
						|
	mov     cx, digbp1      ; set counter for number of subtractions
 | 
						|
	xor     bx, bx
 | 
						|
	clc
 | 
						|
sloop:
 | 
						|
	mov     ax, partpr[bx]  ; subtract a digit at a time
 | 
						|
	sbb     acop[di+bx], ax
 | 
						|
	inc     bx
 | 
						|
	inc     bx
 | 
						|
	loop    sloop
 | 
						|
 | 
						|
	dec     numquot
 | 
						|
	jz      done
 | 
						|
	jmp     wordloop
 | 
						|
 | 
						|
done:
 | 
						|
; handle rounding
 | 
						|
if      _LDATA
 | 
						|
	mov     ax, parm9_      ; get rounding flag
 | 
						|
else
 | 
						|
	mov     ax, parm6_      ; get rounding flag
 | 
						|
endif
 | 
						|
	cmp     ax, 0           ; check if rounding flag set
 | 
						|
	je      noround
 | 
						|
 | 
						|
; see if r >= b/2
 | 
						|
	mov     cx, digbp1
 | 
						|
	mov     si, 0
 | 
						|
	clc
 | 
						|
dloop:
 | 
						|
	rcl     word ptr acop[si], 1            ; double remainder
 | 
						|
	inc     si
 | 
						|
	inc     si
 | 
						|
	loop    dloop
 | 
						|
 | 
						|
; compare 2*r & b
 | 
						|
	mov     bx, digb2
 | 
						|
comrl:
 | 
						|
	mov     ax, acop[bx]
 | 
						|
	cmp     ax, bcop[bx]    ; compare digit
 | 
						|
	ja      round           ; a>b/2
 | 
						|
	jb      noround         ; a<b/2
 | 
						|
	dec     bx
 | 
						|
	dec     bx
 | 
						|
	jns     comrl   ; check next digit, round if r = b/2
 | 
						|
 | 
						|
round:
 | 
						|
	mov     di, dstplc
 | 
						|
roundlp:
 | 
						|
	inc     word ptr es:[di]
 | 
						|
	jnz     noround
 | 
						|
	inc     di              ; if carry, increment next digit
 | 
						|
	inc     di
 | 
						|
	jmp     short roundlp
 | 
						|
 | 
						|
noround:
 | 
						|
if _LDATA
 | 
						|
	pop es
 | 
						|
endif
 | 
						|
 | 
						|
	cproce
 | 
						|
	endps
 | 
						|
	end
 |