campo-sirio/gfm/dmbyp10t.asm
alex ba237a9d91 Patch level : no patch
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
2002-02-26 12:19:02 +00:00

135 lines
2.8 KiB
NASM
Executable File

; int _DivUnsArrByPwrOf10Trunc(a, n, p)
;
; ARGUMENT
; unsigned a[] n-word number to divide
; int n number of digits
; int p power of 10 to divide by
;
; DESCRIPTION
; Divides a n-word 'a' by a power of 10, c = a / 10^p,
; a>=0, p>0, truncating the result. c is correct only if a / 10^p < 2^79.
;
; SIDE EFFECTS
; The value of a is destroyed (it isn't needed later).
;
; RETURNS
; None. (always succeeds)
;
; 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 dmbp10t
p10 dw 1d,10d,100d,1000d,10000d
endds
pseg dmbp10t
cproc _DivUnsArrByPwrOf10Trunc,,_dmbp10t
; load parameters
if _LDATA
mov ax, parm4_ ; get power of 10 to divide by
else
mov ax, parm3_ ; get power of 10 to divide by
endif
cmp ax, 0 ; if dividing by 10^0=1,
je qexit ; nothing need be done
if _LDATA
push es
les di, parm1_ ; get pointer to source & destination
mov bx, parm3_ ; get number of digits
else
mov di, parm1_ ; get pointer to source & destination
mov dx, ds
mov es, dx
mov bx, parm2_ ; get number of digits
endif
cmp ax, 4 ; Is the division by less than 10^4?
jle less4d
d10000:
mov cx, 10000d ; divide by 10000=10^4
d4loop:
push ax ; save ax & bx
push bx
call near ptr dmby1a2 ; division
pop bx ; restore ax & bx
pop ax
sub ax, 4 ; 4 less powers of 10 to divide by
cmp ax, 4 ; are there 4 more left to do?
jg d4loop ; yes, do it again
less4d:
mov si, ax
sal si, 1
mov cx, p10[si] ; load correct power of ten
call near ptr dmby1a2 ; division
if _LDATA
pop es
endif
qexit:
cproce
; the computation routine is separate so it may be called from assembly
dmby1a2:
dec bx ; digits go from 0 to n-1
sal bx, 1 ; want bytes rather than words
;/* skip initial zeroes */
; for(;(q>0)&&(c[q-1]==0);q--);
;
; if (q == 0)
; return(0);
; q--; /* q will be used for subscript */
zeroloop:
mov ax, word ptr es:[di+bx] ; get digit
cmp ax, 0 ; is digit zero?
jne nonzero ; if non-zero, begin divide
dec bx ; next word
dec bx
cmp bx, 0 ; last digit?
jge zeroloop ; if not, process next digit
xor ax, ax ; otherwise, remainder 0
jmp short exit1 ; && division through (0/c=0)
; bl = (unsigned long) b;
; while (q>=0) {
; k = (unsigned long *) &r[q];
; cl = *k / bl;
; c[q] = (unsigned) cl;
; r[q] = (unsigned) (*k - cl * bl);
; q--;
; }
nonzero:
xor dx,dx ; high word zero in first divide
divloop:
div cx ; divide digit
mov word ptr es:[di+bx], ax ; store quotient digit
cmp bx, 0 ; last digit?
je exit2 ; if so, division complete
dec bx ; next digit
dec bx
mov ax, word ptr es:[di+bx] ; get digit
jmp short divloop ; process digit
exit2:
mov ax, dx ; return remainder
exit1:
ret
endps
end