我用汇编语言编写了一个程序来执行一些算术运算。 我收到以下错误,我的cmd已经崩溃了一些大内存转储。错误是:
Prog.exe中0x004011c6处的第一次机会异常:0xC0000005:访问冲突读取位置0x00406000。 Prog.exe中0x004011c6处的未处理异常:0xC0000005:访问冲突读取位置0x00406000。
导致此错误的原因是什么?如何解决?
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
内存转储:
答案 0 :(得分:4)
你的算术不会造成崩溃。在底部,您可以调用Irvine32图书馆的DumpRegs功能,该功能会在顶部显示寄存器。这很好,但崩溃的是对DumpMem的调用。它崩溃了,因为您还没有正确地将参数初始化为 DumpMem 。您需要设置要打印的起始点,大小和值的数量。结果是它开始从意外的位置转储内存,直到它在您的程序无法访问的内存地址失败。这导致了访问冲突。
打印的有用之处可能是结果A
以及其后的3个其他变量。根据 DumpMem 文档:
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
如果要从A
开始打印32位(4字节)SDWORD并在其后包含3个SDWORD,则可以将代码修改为:
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
与访问冲突无关的是您在开始时拥有此代码:
MOV eax, B
SUB eax, C
ADD edx, D
当程序开始运行时,无法保证寄存器为零。在此代码中,您将D
添加到 EDX 并将结果存储在 EDX 中。您可能只想简单MOV EDX, D
而不是使用ADD?