Search code examples
assemblyx86masmirvine32

Access violation error in Assembly Language program


I wrote a program in assembly language to perform few arithmetic operations. I got the following error and my cmd has crashed with some big memory dump. The error was:

First-chance exception at 0x004011c6 in Prog.exe: 0xC0000005: Access violation reading location 0x00406000. Unhandled exception at 0x004011c6 in Prog.exe: 0xC0000005: Access violation reading location 0x00406000.

What is causing this error and how can I fix it?

include Irvine32.inc

.data
A SDWORD ?
B SDWORD 10
C SDWORD 20
D SDWORD 30

.code
main PROC
MOV eax, B
SUB eax, C
ADD edx, D
ADD edx, 3
ADD edx, B
SUB edx, 10
SUB edx, D
SUB eax, edx
MOV A, eax

CALL DumpRegs
CALL DumpMem
exit

main ENDP
END main

The memory dump:

cmd-output


Solution

  • Your arithmetic isn't causing the crash. At the bottom you call the Irvine32 Library's DumpRegs feature that displays the registers at the top. That is fine, but what is crashing is the call to DumpMem. It is crashing because you haven't initialized the parameters to DumpMem properly. You need to set the starting point, the size, and the number of values to print. The result is that it started dumping memory from an unexpected location until it failed at a memory address your program didn't have access to. That caused the access violation.

    The useful thing to print would probably be the result A and the 3 other variables in memory after it. According to the DumpMem documentation:

    DumpMem PROC

     Writes a range of memory to standard output in hexadecimal.
    
     Call args:  ESI = starting offset
                 ECX = number of units
                 EBX = bytes/unit (1,2,or 4)
    
     Return arg: None
    

    If you want to start printing 32-bit (4 byte) SDWORDs starting at A and including the 3 SDWORDs after it you could modify your code to be:

    CALL DumpRegs
    MOV ESI, OFFSET A                 ; Address A is start of memory to print
    MOV EBX, SIZEOF A                 ; Same as MOV EBX, 4
    MOV ECX, 4                        ; Number of 32-bit SDWORDs to print
    CALL DumpMem
    

    Code Observations

    Not related to the access violation is that you have this code at the start:

    MOV eax, B
    SUB eax, C
    ADD edx, D
    

    When your program starts running there is no guarantee that the registers are zero. In this code you add D to EDX and store the result in EDX. You may have intended to simply MOV EDX, D instead of using ADD?