;*****************************************************************************
TITLE         MAIN PROGRAM MUL16(UNSIGNED)
              PAGE           57,80
;-----------------------------------------------------------------------------
; Author: M. Sajjad Alam (University at Albany)
; Revised: Dec 9, 1996
;-----------------------------------------------------------------------------
;   This program multiplies two 16-bit numbers.  The numbers to be multiplied
; are stored in the data segment at MPLY and MCND.  Space is reserved at 
; PRODL and PRODH for the product.
;   The program multiplies unsigned numbers using the right shift algorithm.
; The largest two numbers that can be multiplied are: FFFFh and FFFFh or in
; decimal 65535 and 65535.  For the purpose of testing the program, we suggest
; you test the program for the following examples:
; FFFFh x 10h = FFFF0h, FFFFh x 100h = FFFF00h, FFFFh x 1000h = FFFF000h 
; FFFFh x  Fh = EFFF1h, FFFFh x  FFh = FEFF01h, FFFFh x  FFFh = FFEF001h
; FFFFh x  FFFFh = FFFE0001
; INPUT:   DX  <-  Multiplicand              
;          BX  <-  Multiplier
;          CX  <-  Bit Counter = 10h = 16
; OUTPUT:  AX  <-  High word of product
;          BX  <-  Low Word of product
;-----------------------------------------------------------------------------
; Note the program can be speeded up if we write a macro called BIT1_COUNT
; which could count the number of '1' in the multiplier and store it in reg CX
;*****************************************************************************

SSEG          SEGMENT        PARA STACK  'STACK' ; Start of Stack Segment
              DB             64 DUP('STACK')     ; Reserve 64 bytes
SSEG          ENDS                               ; End of Stack Segment

;*****************************************************************************

DSEG          SEGMENT        PARA PUBLIC 'DATA'  ; Start of data segment
;             Enter here the data words
MCND          DW             0FFFFH              ; Store multiplicand
MPLR          DW             0FFFH                ; Store multiplier
;             Reserve two words for the product
PRODL         DW              ?                  ; Low byte of Product 
PRODH         DW              ?                  ; High byte of Product
;       
DSEG          ENDS                               ; End of data segment
               
;*****************************************************************************

CSEG          SEGMENT        PARA PUBLIC 'CODE'  ; Start of Code Segment
              ASSUME         CS:CSEG, DS:DSEG, SS:SSEG

MUL16          PROC           FAR
;             Set up the Stack  with proper values to return to DOS or DEBUG

              PUSH           DS                  ; Save DS on the stack
              SUB            AX,AX               ; Load 0 into AX
              PUSH           AX                  ; Save 0 on the stack

;             Initialize the Data Segment registers

              MOV            AX,DSEG             ; Store Address DSEG in AX
              MOV            DS,AX               ; Transfer AX to Data Seg Reg

;----------------------------------------------------------------------------
;             Programming task starts here
START:        SUB            AX,AX               ; Store 0 in AX and clear CF
              MOV            BX,MPLR             ; Store multiplier in BX 
              MOV            DX,MCND             ; Store multiplicand in DX
              MOV            CX,16               ; Store # of bits in CX
              RCR            BX,1                ; Rotate BX one bit right
NEXT:
              JNC            SHIFT               ; If CF=1, skip the adding
              ADD            AX,DX               ; Add multipicand to AX
SHIFT:                                           ; Perform right shift of prod 
              RCR            AX,1                ; Right shift of AX thru CF
              RCR            BX,1                ; Right shift CF into BX
              DEC            CX                  ; Decrease bit count by 1
              JCXZ           DONE                ; Done if bit count is 0
              JMP            NEXT                ; Otherwise loop for next bit
DONE:                                            ; Multiplication is finished
              MOV            PRODL,BX            ; Store low word at PRODL
              MOV            PRODH,AX            ; Store high word at PRODH
              RET                                ; return to debug
MUL16         ENDP
CSEG          ENDS
              END            MUL16

