Hello.
I'm writing an x86 program to:
1. read in a set of positive integers from the user
2. store the integers into an array
3. call a procedure to calculate the average
4. output the average to the screen
I'm utilizing 2 files:
main.asm ; the main program
avg.asm ; a procedure called by the main program
My main.asm file looks like this:
Code:
.586
.MODEL FLAT
INCLUDE io.h
.STACK 4096
.DATA
; VARIOUS PROMPTS USED FOR USER INPUT/OUTPUT
elementPrompt BYTE "[Negative cancels input] Enter element into array: ", 0
string BYTE 20 DUP (?)
resultLbl BYTE "Array Information:", 0
averageLbl BYTE "Average of", 0
elementLbl BYTE "Elements:", 0
outMsgLbl BYTE 80 DUP (?)
errorLbl BYTE "Zero input elements; program terminating", 0
; VARIABLES USED FOR STORAGE AND CALCULATION
numberElements DWORD 11 DUP (?), 0
numArray DWORD 100 DUP (?)
arrayAvg DWORD 11 DUP (?), 0
EXTRN avg:PROC
.CODE
_MainProc PROC
; INITIALIZE COUNT AND OBTAIN ARRAY ADDRESS:
mov numberElements, 0 ; Initialize elements to 0
lea ebx, numArray ; Obtain address of array
; WHILE LOOP FOR USER INPUT:
whileLoop:
input elementPrompt, string, 20 ; Prompt user
atod string ; Convert to double word
cmp eax, 0 ; Test for negative number
jl endWhile ; If negative, exit loop
mov [ebx], eax ; Move number into array
inc numberElements ; Increment numberElements
add ebx, 4 ; Obtain next address
loop whileLoop ; Continue loop
endWhile:
; TEST FOR 0 INPUT
cmp numberElements, 0 ; Test for zero input
jg next ; If input, skip termination
output resultLbl, errorLbl ; If zero input, output error
jmp quit ; and terminate
; PROCEED
next:
lea eax, numArray ; load array address
push eax ; push array onto stack
lea eax, numberElements ; load count address
push eax ; push count onto stack
lea eax, arrayAvg ; load average address
push eax ; push average onto stack
call avg ; call average
; proceed with output
; ..
; ..
; etc
; TERMINATE PROGRAM
quit:
mov eax, 0 ; exit with return code 0
ret
_MainProc ENDP
END ; end of source code
and my avg.asm file looks like this:
Code:
.586
.MODEL FLAT
.CODE
avg PROC
push ebp ; save register values
mov ebp, esp ; mov esp into ebp
push eax ; save register values
push ebx
push ecx
push edx
mov eax, [ebp+8] ; obtain address of arrayAvg
mov edx, [ebp+12] ; obtain address of numberElements
mov ebx, [ebp+16] ; obtain address of numArray
mov ecx, edx ; move number of elements into count for looping
mov eax, 0 ; Initialize average to 0
forLoop:
add eax, [ebx] ; add current array element to eax -- ?UNHANDLED EXCEPTION?
add ebx, 4 ; obtain next array value
loop forLoop ; loop, decrementing ecx
div edx ; divide eax (total) by number of elements
push eax ; push average onto the stack
ret
avg ENDP
END
I am getting an "Unhandled Exception" error and my program breaks at 'add eax, [ebx]' within my average procedure. More specifically, visual studio pops up with a window and says "Unhandled exception at 0x004115f7 in windows32.exe: 0xC0000005: Access violation reading location 0x0041a000.", with the option to break or continue. The debug output says "First-chance exception at 0x004115f7 in windows32.exe: 0xC0000005: Access violation reading location 0x0041a000.
Unhandled exception at 0x004115f7 in windows32.exe: 0xC0000005: Access violation reading location 0x0041a000.
The program '[560] windows32.exe: Native' has exited with code -1073741819 (0xc0000005)."
What am I doing wrong?