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
 |