汇编语言程序中的访问冲突错误

时间:2018-03-15 13:35:46

标签: assembly x86 masm irvine32

我用汇编语言编写了一个程序来执行一些算术运算。 我收到以下错误,我的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

内存转储:

cmd-output

1 个答案:

答案 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?