;******************************************************************
; Program with a procedure that averages consecutive positive words
;******************************************************************

stk       segment     stack
          dw          16 dup (?) ;memory for stack
stk       ends

data      segment
list1     dw          4,8,-1     ;first data set
list2     dw          7,5,2,8,-1 ;second data set
avg1      dw          ?          ;first data set average
avg2      dw          ?          ;second data set average
data      ends

code      segment
          assume      cs:code,ds:data
main      proc        far
          push        ds
          sub         ax,ax
          push        ax
          mov         ax,data
          mov         ds,ax
          mov         si,offset list1    ;address of 1st list
          mov         di,offset avg1     ;address of 1st average
          call        average            ;compute average
          lea         si,list2           ;address of 2nd list
          lea         di,avg2            ;address of 2nd average
          call        average            ;compute average
          ret                            ;all done
main      endp

;*******************************************************************
; AVERAGE PROCEDURE -- COMPUTES AVERAGE OF A LIST OF POSITIVE WORDS
; INPUT PARAMETER: SI, SHOULD CONTAIN OFFSET OF THE LIST
; "OUTPUT" PARAMETER: DI, SHOULD CONTAIN OFFSET OF RESULT
; RESULT WILL BE STORED IN WORD POINTED TO BY DI
; USES DX/AX AS A RUNNING SUM, CX AS A COUNTER
; RESULT WILL BE 0 IF LIST WAS EMPTY
;*******************************************************************
average   proc        near
          mov         cx,0             ;initialize counter
          mov         dx,0             ;initialize running sum
          mov         ax,0
top:      cmp         word ptr [si],0  ;is next number negative?
          jl          fin              ;if so go to fin
          add         ax,[si]          ;if not add in next number
          jnc         ok               ;no carry, so dx is ok
          inc         dx               ;a carry ==> msw is 1 greater
ok:       inc         cx               ;increment counter
          add         si,2             ;point to next number
          jmp         top              ;do it again
fin:      cmp         cx,0             ;was list empty?
          je          done             ;empty list, so we're done
          div         cx               ;divide to get the average in ax
done:     mov         [di],ax          ;store result in correct location
          ret
average   endp
code      ends
          end         main