Search code examples
exceptionassemblyx86visual-studio-2019masm

Expection Thrown/Exception Unhandled in Visual Studio 2019


In the highlighted line of my code, I get the message "Exception thrown at 0x002C36C9 in project.exe: 0xC0000005: Access violation reading location 0x0058C00A"

I have been trying everything to get rid of it but it just doesn't work and I am in desperate need of help. The code is not completely done yet but it should run somewhat. The purpose of the code is to copy elements from arrayS to arrayD starting from the index received from keyboard input. Someone please help me, the code looks perfectly fine so I relaly don't know what is wrong

See highlighted line

I dont really know how to explain what I've tried what I am trying to do is quite simple, which is why I do not understand why I am getting this error.

include Irvine32.inc
ExitProcess proto, dwExitCode: DWORD

.data
  arrayS    BYTE    1, 2, 3, 4, 5   ;array (SOURCE)
  numEl = LENGTHOF arrayS
  arrayD    BYTE    numEl DUP(0)    ;array (DESTINATION)
  startIndex    BYTE    ?        ;store the character in this variable
  exit  EQU     <Invoke ExitProcess,0>
  header    BYTE    "----- Array Copier -----",0
  indexq    BYTE    "Index (0 - 4): ",0
  invalidIn BYTE    "Invalid Input. Try again.",0
  termination   BYTE    "----- Program Terminated -----",0



.code

userInput PROC
  mov edx, OFFSET indexq
  call WriteString
  call ReadInt
  call crlf
  mov startIndex, al

  ret
userInput ENDP

displayTitle PROC 
  mov edx, OFFSET header
  call WriteString
  call crlf

  ret
displayTitle ENDP

copyArray PROC

  mov esi, OFFSET arrayS
  mov edi, OFFSET arrayD
  movzx ebx, startIndex
  mov ecx, numEl

copying:
  mov al, [esi + ebx]
  mov [edi], al
  inc esi
  inc edi
  loop copying

  ret
copyArray ENDP

showArray PROC uses ecx
  mov ecx, numEl
  call crlf
  show:
  mov eax, [edi]                ;moving array element to be displayed
  call WriteInt
  call crlf
  add edi, type arrayD      ;moving through array elements to display
  loop show

  ret
showArray ENDP

main PROC
  call displayTitle
  call userInput
  call copyArray
  call showArray

  exit
main ENDP
END main
  

EDIT New version based on an answer

include Irvine32.inc
ExitProcess proto, dwExitCode: DWORD

.data
  arrayS    BYTE    1, 2, 3, 4, 5   ;array (SOURCE)
  numEl = LENGTHOF arrayS
  arrayD    BYTE    numEl DUP(0h)   ;array (DESTINATION)
  ptr1  DWORD   arrayS
  ptr2  DWORD   arrayD

  startIndex    BYTE    ?        ;store the character in this variable

  exit  EQU     <Invoke ExitProcess,0>
  header    BYTE    "----- Array Copier -----",0
  indexq    BYTE    "Index (0 - 4): ",0
  invalidIn BYTE    "Invalid Input. Try again.",0
  termination   BYTE    "----- Program Terminated -----",0



.code

userInput PROC ;uses ebx ecx eax
beginning:
  mov edx, OFFSET indexq
  call WriteString
  call ReadInt

check:
  mov ebx, 4h           ;check if below 4, then check 2 if below
  cmp eax, ebx
  jbe check2

error:
  mov edx, OFFSET invalidIn
  call WriteString
  call crlf
  jmp beginning

check2:
  mov ebx, 0h       ;check if above zero, then done if above
  cmp eax, ebx
  jnae error

done:
  mov startIndex, al
  ret

userInput ENDP

displayTitle PROC 
  mov edx, OFFSET header        ;displays title
  call WriteString
  call crlf

  ret
displayTitle ENDP

copyArray PROC ;uses ebx ecx 

  mov esi, OFFSET arrayS        ;moving addresses of arrays into the registers
  mov edi, OFFSET arrayD
  add esi, DWORD PTR startIndex
  mov ecx, numEl
  sub ecx, DWORD PTR startIndex

copying:
  mov al, [esi]     ;copying array elements from arrayS to array D
  mov [edi], al
  inc esi
  inc edi
  loop copying

  ret
copyArray ENDP

showArray PROC ;uses ecx 
  mov edi, OFFSET arrayD
  mov ecx, numEl
show:
  mov eax, 0
  mov al, [edi]             ;moving array element to be displayed
  call WriteHex
  mov al, 'h'
  call WriteChar
  call crlf
  add edi, type arrayD      ;moving through array elements to display
  loop show

  ret
showArray ENDP

main PROC
  call displayTitle
  call userInput
  call copyArray
  call showArray

  exit
main ENDP
END main

Solution

  • This reviews the latest version of the code

    In userInput, the code in check2 is totally redundant because the condition of a number ever being below zero is simply not possible.
    Lots of numbers are less than zero, but none are below zero!
    And you can compare to the hardcoded number 4 without using EBX, but really you should be comparing with numEl:

    check:
      cmp   eax, numEl     ; numEl is 5 in casu
      jb    done           ; We now k n o w that EAX is [0,4]
    

    In copyArray, the byte-sized startIndex is being used as if it were a dword. Since you apparantly must keep it a byte, change the code as follows:

      mov   edi, OFFSET arrayD
      movzx eax, BYTE PTR startIndex
      mov   esi, OFFSET arrayS
      add   esi, eax
      mov   ecx, numEl
      sub   ecx, eax
    copying:
      mov   al, [esi]
      mov   [edi], al
      inc   esi
      inc   edi
      loop  copying
      ret
    

    In showArray, the code displays the full memory for the destination array eventhough probably only a portion of it got filled with copied elements.

      mov   ebx, OFFSET arrayD
      movzx eax, BYTE PTR startIndex
      mov   ecx, numEl
      sub   ecx, eax
    show:
      movzx eax, BYTE PTR [ebx]
      call  WriteHex
      mov   eax, 'h'
      call  WriteChar
      call  crlf
      inc   ebx
      loop  show
      ret