Reputation: 313
The code below computes the average of 20 user entered numbers. It works fine when I disable ShowMsg msg2
(make it a comment), but when its enabled, I get this error :
INT 21h, AH=09h -
address: 0711E
byte 24h not found after 2000 bytes.
; correct example of INT 21h/9h:
mov dx, offset msg
mov ah, 9
And I cant figure what the problem is.
ShowMsg macro msg
mov ah, 09h
mov dx, offset msg
int 21h
endm
NewLine macro
mov ah, 02h
mov dl, 0ah
int 21h
mov dl, 0dh
int 21h
endm
data segment
sum dd 0
num dd 0
array dd 20 dup(0)
msg1 db 'Enter 20 numbers:', '$'
msg2 db 0dh,0ah,'Average: ', '$'
data ends
stack segment
dw 100 dup(?)
stack ends
code segment
assume cs:code, ds:data, ss:stack
Main Proc Far
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
ShowMsg msg1
lea si, array
call GetNum
;**** PROBLEM IS HERE! ****
ShowMsg msg2
lea si, array
call Average
mov ah, 4ch
int 21h
Main endp
;Gets 20 numbers(max 6 digit) from user
;and puts them in the array
;which its effective address is in SI.
proc GetNum
push si
mov ch, 20
NextNumber:
NewLine
mov cl, 6
mov word ptr num, 0
mov word ptr num+2, 0
GetChar:
mov ah, 07h
int 21h
cmp al, 0dh
jz Flag
cmp al, 30h
jb GetChar
cmp al, 39h
ja GetChar
mov ah, 02h
mov dl, al
int 21h
sub al, 30h
mov bl, al
mov di, 10
mov ax, num
mul di
mov num, ax
push dx
mov ax, num+2
mul di
mov num+2, ax
pop dx
add num+2, dx
mov bh, 0
add num, bx
adc word ptr num+2, 0
dec cl
jnz GetChar
Flag:
mov ax, num
mov dx, num+2
mov [si], ax
mov [si+2], dx
add si, 4
dec ch
jnz NextNumber
pop si
ret
GetNum endp
;Computes the average of numbers in the array
;which its effective address is in SI.
proc Average
push si
mov cx, 20
Average_Next:
mov ax, [si]
add word ptr sum, ax
mov ax, [si+2]
adc word ptr sum+2, ax
add si, 4
loop Average_Next
mov bx, sum
mov bp, sum+2
mov di, 20
call Div32
call Show
pop si
ret
Average endp
;Divides BP:BX to DI,
;returns the quotient to BP:BX,
;remainder to DX
proc Div32
mov dx, 0
mov ax, bp
div di
mov bp, ax
mov ax, bx
div di
mov bx, ax
ret
Div32 endp
;Prints the number in BP:BX
proc Show
mov di, 10
mov cx, 0
Show_Next1:
call Div32
push dx
inc cx
or bp, bx
jnz Show_next1
Show_next2:
pop dx
add dl, 30h
mov ah, 02h
int 21h
loop Show_next2
ret
Show endp
Upvotes: 2
Views: 670
Reputation: 10381
I tested your code in EMU8086, and this is the solution that worked for me, next is your data segment with 5 little changes :
data segment
sum dw 0 ;<==========================
dw 0 ;<==========================
num dw 0 ;<==========================
dw 0 ;<==========================
msg1 db 'Enter 20 numbers:', '$'
msg2 db 0dh,0ah,'Average: ', '$'
array dd 20 dup(0) ;<==========================
data ends
In the procedure "GetNum", as the characters are captured, the address of the array gets overwritten by the address of "msg1", so, the captured numbers overwrite "msg1" and "msg2". Moving the array to the end of the data segment fixed it (for me). You have to test it to see if it works for you too.
More changes in variables "sum" and "num", because the size "DD" gave me problems. The way to fix this is to use two "DW", so there is no problem with sizes when using AX and DX with "num" and "sum".
Upvotes: 1