ford
ford

Reputation: 25

calculate average number an array (asssembly)

data segment
  a db 0,3,5,7,5 
  average db ?
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:    
mov ax,@data
mov ds,ax
mov es,ax

mov ax,0
mov bl,5
mov cx,5
lea si,a

dong:
add ax,[si]
inc si
dec cx
cmp cx,0
jne dong
jmp bak

bak:    
div bl           ;ax/5=al
mov average,al
mov ax, 4c00h
int 21h  
ends

end start

I can not calculate the average...What is missing in my codes

Upvotes: 1

Views: 5114

Answers (1)

Fifoernik
Fifoernik

Reputation: 9899

a db 0,3,5,7,5

With an array that is defined to contain byte values, you need to also read these values as bytes! The instruction add ax,[si] is reading these values as words. That's clearly wrong.

There're a few solutions here:

  • Do a cascade a byte-sized additions

    add al, [si]  ;Add 1 byte-sized array element to AL
    adc ah, 0     ;Takes care of a potential carry from previous addition
    
  • Read the byte value in the low part of a pre-zeroed word register, then do a word-sized addition

    mov dl, [si]  ;Read 1 byte-sized array element in DL, DH was zeroed beforehand!
    add ax, dx    ;Add to result in AX
    

The rest of your program is OK, but it can be improved a bit.

mov ax,0

Clearing a register is better done via XOR-ing the register with itself. So here it becomes xor ax, ax.

dec cx
cmp cx,0
jne dong

Because the dec cx instruction already sets the flags including the zero flag (ZF) that you want, there's no need to use cmp cx,0 before looping back.

jmp bak

bak:

This jmp bak is useless since the code can just as easily fall through.


Applying the above gives:

 xor ax, ax    ;Set AX=0
 mov cx, 5
 lea si, a
dong:
 add al, [si]  ;Add 1 byte-sized array element to AL
 adc ah, 0     ;Takes care of a potential carry from previous addition
 inc si
 dec cx
 jnz dong
 mov cl, 5
 div cl        ;AX/5 -> AL
 mov average, al

Note that I avoided using BL simply by re-using CL.

Upvotes: 2

Related Questions