News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

ACCESS VIOLATION EXCEPTION

Started by DaTrinity22, December 11, 2017, 07:48:22 AM

Previous topic - Next topic

DaTrinity22

Hey guys, so I have this final project due today and I have no way of contacting the professor, as he does not respond to emails. I cannot for the life of me, figure out why I am getting this exception. It is breaking when calling loadOlympian during the last iteration of the loop in LoadAllOlympians and I am getting the Frame not in module message, so I cannot view the stack frame. I will attach my code and the input text file below. Any help would be greatly appreciated as this project is due in a little over 2 hours and I cannot figure out why this exception is being thrown.

include Irvine32.inc

olympian STRUCT
athlete BYTE 32 DUP('a') ; 32 bytes
country BYTE 32 DUP('c') ; 32
gender BYTE 'x' ; 1
ALIGN DWORD ; add 3 bytes
medals DWORD -1,-1,-1 ; gold silver bronze (96)
olympian ENDS         ; 164 total

; define some constants for global use
FSIZE = 100 ; max file name size
BSIZE = 1000 ; buffer size
LINESIZE = 100 ; max input line size
CR = 0Dh ; c/r
LF = 0Ah ; line feed
ASTERISK = 2Ah ; asterisk for new entry
NULL = 00h ; null character
SPACE = 20h ; space character
MAXNUM = 5 ; number of olympians

.data
filename BYTE FSIZE DUP(?) ; array to hold the file name
buffer BYTE BSIZE DUP(?) ; buffer to hold the file contents
prompt BYTE "Enter a filename: ",0 ; prompt for a string
ferror BYTE "Invalid input...",0         ; error message


olist olympian <>,<>,<>,<>,<> ; list of 5 olympians

; for output listing
outname    BYTE "Name: ",0
outcountry BYTE "Country: ",0
outgender  BYTE "Gender: ",0
outmedals  BYTE "Medals: ",0
outtotal   BYTE "Total Medals: ",0

.code
main PROC
    ; load the data from a file - push the arguments in reverse order
push BSIZE ; data buffer size
push OFFSET buffer ; point to the start of the buffer
push FSIZE ; file name size
push OFFSET filename ; point to the start of the string
push OFFSET prompt ; output the prompt
call loadFile ; load the buffer
cmp eax,0 ; nothing read, bail out
jz ERROR

;;;;;DELETE THE FOLLOWING CODES OF LINE BELOW, USED SIMPLY FOR TESTING
push OFFSET olist ;
push OFFSET buffer ;
push LINESIZE ;
call loadALLOlympians ;

; file loaded correctly, process and output the data

jmp DONE ; done processing data, jump to the end
ERROR:
    mov edx,OFFSET ferror ; output error message
call WriteString ; uses edx
call CrLf
DONE:
call WaitMsg ; wait for user to hit enter
invoke ExitProcess,0 ; bye
main ENDP



; prompts for a file name and reads contents into a buffer
; receives:
; [ebp+8] = (null terminated) prompt string
; [ebp+12] = pointer to file name string
; [ebp+16] = max size of file name string
; [ebp+20] = pointer to buffer array
; [ebp+24] = max size buffer
; returns:
; eax = number of bytes read, zero on an error
loadFile PROC
push ebp ; save the base pointer
mov ebp,esp ; base of the stack frame
sub esp,4 ; create a local variable for the return value
pushad ; save all of the registers (lazy)
; prompt for the file name
    mov edx,[ebp+8] ; output the prompt
call WriteString         ; uses edx 
; get the file name, open the file
mov edx,[ebp+12] ; point to the start of the file name string
mov ecx,[ebp+16] ; max size for file name
call ReadString ; load the file name (string pointer in edx, max size in ecx)
call OpenInputFile ; open the file (expects name in edx, max size in ecx)
mov ebx,eax ; save the file pointer (returned in eax)
cmp eax,INVALID_HANDLE_VALUE ; check for a valid file pointer
je BAD ; bail out on a failure
; load the buffer wit the contents of the file
mov edx,[ebp+20] ; point to the start of the buffer
mov ecx,[ebp+24] ; max size of the buffer
call ReadFromFile ; gets file handle from eax (loaded above)
mov DWORD PTR [ebp-4],eax ; save the number of bytes in local variable
mov eax,ebx ; restore the file pointer for closing (saved above)
call CloseFile ; close the file
jc BAD ; if carry fag set, it's an error
jmp OK
BAD:
call WriteWindowsMsg ; got an error, display it
mov DWORD PTR [ebp-4],0 ; error: set the number of bytes read to zero
OK: ; clean up
popad ; restore the registers
mov eax,DWORD PTR [ebp-4] ; save the number of bytes read for return in eax
mov esp,ebp ; remove local varfrom stack
pop ebp
ret 20
loadFile ENDP



; copies bytes from the input buffer to a member of the Olympian struct
; RECEIVES:
; [ebp+8] = LINESIZE- the max number of bytes to read
; [ebp+12] = OFFSET Olympian.<member>- pointer to a member of the Olympian struct
; [ebp+16] = OFFSET buffer- pointer to the next character to read from the buffer
; RETURNS:
; eax = pointer to the next character to read from the buffer
bufferCopy PROC USES ebx ecx edx
LOCAL ctr:BYTE ; creates a local counter variable
mov ctr, 0 ; sets counter to 0
mov ebx, [ebp+16] ; stores address of char in buffer pointed to by the pointer param in ebx (B for Buffer)
mov ecx, [ebp+12] ; stores address of the member of the Olympian struct param in edx
jmp START ; jump to the start label since counter is zero and no bytes have been read.
NEXTCHAR:
inc bl ; moves to the next char in the buffer
inc cl ; moves to the next empty character in member of Olympian struct
START:
mov dl, [ebx] ; moves the next character in the buffer to register al
cmp dl, CR ; checks if next character is a carriage-return
JZ ENDLINE ; if the next char is a carr-ret, jump to ENDLINE label
mov [ecx], dl ; move current char in buffer to next empty char in member of Olympian struct (register al is now clear)
inc ctr ; increments the counter
mov dl, ctr ; moves the counter to register al
cmp dl, [ebp+8] ; checks if the counter equals or exceeds LINESIZE
JC NEXTCHAR ; if counter is less than LINESIZE, jump to READCHAR label (loop)
jmp EXITPROC ; else if counter is not less than LINESIZE, jump to EXIT label (exit proc)
ENDLINE:
mov dl, NULL ; moves the null character into register al
mov [ecx], dl ; null-terminates the member of the Olympian struct
EXITPROC:
add ebx, 2 ; skips the line feed character in the buffer
mov eax, ebx ; moves the next char to be read from buffer into ebx to be returned (ecx+ctr+2 skips the line feed char)
ret 12
bufferCopy ENDP


; reads information from the buffer and loads it into an Olympian struct
; RECEIVES:
; [ebp+8] = LINESIZE- the max number of bytes to read for each member of the struct (passed to bufferCopy)
; [ebp+12] = OFFSET buffer- pointer to the beginning of the information for the current Olympian
; [ebp+16] = OFFSET olist- pointer to the next element in the array of Olympian structs
; RETURNS:
; eax = pointer to the beginning of the information for the next Olympian
loadOlympian PROC USES ebx ecx edx esi
LOCAL medal[3]:BYTE, numParse:BYTE ; creates local variables
push [ebp+12] ; passes the buffer to bufferCopy
mov ebx, [ebp+16] ; moves the address of the athlete member into ebx
push ebx ; passes the athlete member of the current Olympian to bufferCopy
push [ebp+8] ; passes the max line size to bufferCopy
call bufferCopy ; calls bufferCopy

push eax ; passes the address of the next char to read from the buffer to bufferCopy
add ebx, SIZEOF Olympian.athlete           ; moves the address of the country member into ebx
push ebx ; passes the country member of the current Olympian to bufferCopy
push [ebp+8] ; passes the max line size to bufferCopy
call bufferCopy ; calls bufferCopy

push eax ; passes the address of the next char to read from the buffer to bufferCopy
add ebx, SIZEOF Olympian.country           ; moves the address of the gender member into ebx
push ebx ; passes the gender member of the current Olympian to bufferCopy
push [ebp+8] ; passes the max line size to bufferCopy
call bufferCopy ; calls bufferCopy

add ebx, 3 ; skips 3 bytes to align the Double Words
mov numParse, 0 ; sets numParse to 0
add ebx, SIZEOF Olympian.gender ; moves the address of the medals array into register ebx

MEDALS:
push eax ; passes the address of the next char to read from the buffer to bufferCopy
lea esi, medal ; gets the address of the medal string
push esi ; passes the address of the string used to store the medal counts to bufferCopy
push [ebp+8] ; passes the max line size to bufferCopy
call bufferCopy ; calls bufferCopy

push eax ; pushes eax to the stack to preserve the address of next char to read from buffer
mov edx, esi ; moves the address of the string containing # of gold medals into edx for passing to ParseInteger32
mov ecx, SIZEOF medal ; moves the length of the string into ecx for passing to ParseInteger32
call ParseInteger32 ; calls ParseInteger32
mov [ebx], eax ; moves the gold medal count into the medals array
add ebx, TYPE Olympian.medals         ; increases the index of the array by 1
inc numParse ; increments numParse
pop eax ; pop eax from the stack to get the address of the next char to read from buffer

cmp numParse, 3 ; checks to see if numParse equals 3
jnz MEDALS ; if numParse is less than 3, jump to MEDALS label.

ret 12
loadOlympian ENDP

; calls loadOlympian to transfer data from the memory buffer into the array of olympian structs
; RECEIVES:
; [ebp+8] = LINESIZE - the max number of bytes to read for each member of the struct (passed to loadOlympian)
; [ebp+12] = OFFSET buffer- pointer to the beginning of the information to enter into the olympian structs
; [ebp+16] = OFFSET olist- pointer to the beginning of the array of Olympians
; RETURNS:
; eax = number of Olympians read
loadAllOlympians PROC USES ebx ecx
LOCAL numOlympians:BYTE ; creates local variable

mov numOlympians, 0 ; sets numOlympians to 0
mov ebx, [ebp+16] ; moves the address of olist into ebx
mov eax, [ebp+12] ; moves the address of the buffer into eax

LOAD:
push ebx ; passes the address of the next Olympian to load to loadOlympian
push eax ; passes the address of the information in the buffer to load into the next Olympian to loadOlympian
push [ebp+8] ; passes the max line size to loadOlympian
call loadOlympian ; calls loadOlympian

inc numOlympians ; increments numOlympians
cmp numOlympians, MAXNUM ; checks to see if the olist is full
jz EXITPROC ; if olist is full, jump to label EXIT
mov cl, [eax] ;
cmp cl, ASTERISK ; checks to see if the next char is an asterisk
jz EXITPROC ; if the next char is not an asterisk
add ebx, TYPE Olympian ; increases the index of olist by 1
jmp LOAD ; jump to LOAD

EXITPROC:
mov al, numOlympians ; moves numOlympians into eax to be returned
ret 12 ;

loadAllOlympians ENDP
END main


INPUT FILE:
Michael Phelps
USA
M
23
3
2
Larisa Latynina
USSR
F
9
5
4
Paavo Nurmi
Finland
M
9
3
0
Mark Spitz
USA
M
9
1
1
Carl Lewis
USA
M
9
1
0
*

jj2007

Zip the exe and attach it here, maybe we can at least find out WHERE it crashes. Nobody here uses irvine.inc 8)

DaTrinity22

Ok, the only procedure used from Irvine is ParseInteger32 and all that does in this program is converts the medal count from type byte to type dword to fit in the struct. I attached the entire VS folder of the project.

fearless

At a quick look im guessing its 0 based index of numOlympians and checking against max amount. so really you should only be going as high as (max no -1), as indexentry 0 (numOlympians) is 1st olympian, indexentry 1 is 2nd olympian, indexentry 2 is third olympian, indexentry 3 is fourth olympian and indexentry 4 is fifth olympian - which should be your max as you only have 5 structures for 5 olympians, if its goes over by another then indexentry 5 is really the 6th olympian and no structure defined for that, hence crash.

DaTrinity22

I don't think it is that because I increase it to 1 and check the value immediately after loading an Olympian. So if I start numOlympians at 1, it only loads 4 olympians.

DaTrinity22

I think I figured it out. I had been increasing bl and cl in bufferCopy instead of ebx and ecx, so it was trying to insert the filename into the medal count.

jj2007

Yes, it crashes in LoadOlympian when Carl Lewis is loaded. One of the buffercopy calls overwrites the stack area.

And this is no good with pointers:
   mov ebx, [ebp+16]            ; stores address of char in buffer pointed to by the pointer param in ebx (B for Buffer)
   mov ecx, [ebp+12]            ; stores address of the member of the Olympian struct param in edx
   jmp START                  ; jump to the start label since counter is zero and no bytes have been read.
NEXTCHAR:
   inc bl                     ; moves to the next char in the buffer   
   inc cl                     ; moves to the next empty character in member of Olympian struct      

Congrats, you solved it yourself :t