UMBC CMSC 211

UMBC | CSEE


Working with Multiple Precision Numbers

Let's look at the stack for this program:

;; MPPUTDEC.ASM--Display a multiple-precision number on the CRT
;;  in decimal.  Positive numbers only are accepted.  No error
;;  checking is done.
;;
;;  Calling Sequence:
;;
;;	push	pointer to number
;;	push	words in number
;;	EXTRN	MPPutDec : NEAR
;;	call	MPPutDec
;;
;;  Program text from "Assembly Language for the IBM PC Family" by
;;   William B. Jones, (c) Copyright 1992, 1997, Scott/Jones Inc.
;;
INCLUDE	PCMAC.INC
	.MODEL	SMALL

	.CODE
	PUBLIC	MPPutDec
APtr	EQU	DWORD PTR [bp+6]
Len	EQU	WORD PTR [bp+4]
NZD	EQU	BYTE PTR [bp-3] ;	Has a non-zero digit occurred
DigCt	EQU	BYTE PTR [bp-4] ;	Number of digits pushed onto stack
NumLeft	EQU	-6 ;		Offset to left word of number to put
MPPutDec	PROC
	push	bp
	mov	bp, sp
	push	ds
	sub	sp, 2 ;		Storage for DigCt, NZD
;
;  First--move the number to local storage, where it can be altered
;
	mov	ax, Len
	mov	cx, ax
	shl	ax, 1 ;	Get number of bytes
	sub	sp, ax ;	 .and allocate that much space on stack
	mov	bx, sp ;	Offset to first word of dest on stack
	lds	si, APtr ;	ds:si --> A
	sub	bx, si ;	bx := stack offset - A
MovIn:
	mov	ax, [si]
	mov	ss:[bx + si], ax ;	note ss: override!!
	add	si, 2
	loop	MovIn

	mov	DigCt, 0
	mov	bx, 10 ;	The divisor
;
;		repeat  ... until NZD = 0
;
DigLoop:
	mov	NZD, 0 ;	indicates no non-zero digits in quotient
;
;	compute NumLeft := NumLeft div 10; remainder --> dx
;
	mov	si, NumLeft ;	Left end in fixed position rel bp
	mov	cx, Len
	mov	dx, 0 ;		Initial high-order bits of dividend
MPDivideBy10:
	mov	ax, [bp+si] ;	dx:ax := prev remdr:brought down
;						next digit
	div	bx
	mov	[bp+si], ax
	test	ax, ax
	jz	ZeroResult
	mov	NZD, 1 ;	Quotient is non-zero; another step needed
ZeroResult:
	sub	si, 2
	loop	MPDivideBy10 ;	End of divide by 10

	add	dl, '0' ;	Convert final remainder to ASCII digit
	push	dx
	inc	DigCt

	cmp	NZD, 0
	jne	DigLoop ;	End of repeat ... until
;
;		All digits computed and pushed on the stack
;
	mov	cl, DigCt
	sub	ch, ch
PutLoop:
	pop	ax
	_PutCh	al
	loop	PutLoop

	mov	ds, [bp-2] ;	Restore and quit
	mov	sp, bp
	pop	bp
	ret	6
MPPutDec	ENDP
	END


UMBC | CSEE