在我的代码中突出显示的一行中,我得到消息“Exception thrown at 0x002C36C9 in project.exe:0xC0000005:阅读位置0x0058C00A时发生访问冲突”
我一直在尝试一切摆脱它,但它只是不工作,我迫切需要帮助。代码还没有完全完成,但它应该运行一些。代码的目的是复制元素从arrayS到arrayD从索引收到从键盘输入开始。有人请帮助我,代码看起来很好,所以我relaly不知道是什么错了
See highlighted line
我真的不知道如何解释我已经尝试了什么,我试图做的是很简单的,这就是为什么我不明白为什么我得到这个错误。
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
编辑基于答案的新版本
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
2条答案
按热度按时间s3fp2yjn1#
查看最新版本的代码
在 userInput 中,* check 2 * 中的代码完全是多余的,因为数字永远小于零的条件根本不可能。
很多数字都 * 小于 * 零,但没有一个 * 小于 * 零!
你可以在不使用EBX的情况下与硬编码的数字4进行比较,但实际上你应该与 numEl 进行比较:
在 copyArray 中,字节大小的 startIndex 被当作双字使用。由于您显然必须将其保留为字节,因此更改代码如下:
在 showArray 中,代码显示目标数组的全部内存,即使可能只有一部分内存被复制的元素填充。
fslejnso2#
这并不使用地址 startIndex 处的字节,而是使用 startIndex 本身的地址。
在循环之前,将字节加载到寄存器中:
提示:如果你将 startIndex 定义为
DWORD
,那么你可以这样写:以及:
进一步检查会发现这些其他错误
userInput
cmp
就可以完成这项工作:copyArray
只有当 startIndex 恰好为0时,使用 numEl 初始化ECX才是正确的。但是使用更大的 startIndex,您可以 * 复制的数组元素的数量会减少。否则,您将从数组外部复制垃圾。
showArray
您忘记了将地址放入EDI寄存器中。在这里,您也只能清楚地显示之前实际复制的那些元素。