运行循环时 MASM x86 访问冲突

Posted

技术标签:

【中文标题】运行循环时 MASM x86 访问冲突【英文标题】:MASM x86 Access Violation While Running Loop 【发布时间】:2016-02-28 17:41:23 【问题描述】:

我有一个两字节整数数组,我用随机的 3 位数字填充它,使用 ESI 遍历数组。当我尝试访问数组的第 9 个元素并将其存储在 ESI 中时,我遇到了访问冲突。

ARRAYSIZE = 200

.data
list        WORD    ARRAYSIZE   DUP(?)

fillArray PROC
    push    OFFSET list
    mov     esi, [esp] ;GET ADDRESS OF FIRST ELEMENT INTO ESI
    mov     ecx, request ;NUMBER OF ELEMENTS TO BE ADDED

ArrFill:
    ;calculate random 3-digit number, store in eax
    dec     ecx
    mov     [esi], eax ;THIS IS THE LINE THAT THROWS THE EXCEPTION
    sub     esi, 2
    cmp     ecx, 0
    jnz     ArrFill

抛出异常:访问冲突写入位置0x00405FFE(抛出时ESI的值)。

当我将数组更改为 4 字节整数时,我还会因为尝试访问同一地址的数组的第 5 个元素而遇到访问冲突。

【问题讨论】:

数组有多大,每个值都是 16 位,但你允许多少个值? 编辑:更新代码以添加更多信息。 【参考方案1】:
push    OFFSET list
mov     esi, [esp] ;GET ADDRESS OF FIRST ELEMENT INTO ESI

为什么不用mov esi, OFFSET list简单地将偏移量分配给ESI

mov     [esi], eax ;THIS IS THE LINE THAT THROWS THE EXCEPTION

由于数组包含单词,你只能写AX的内容,不能写EAX!使用mov [esi], ax

sub     esi, 2

要遍历数组,您需要添加到指针,而不是从中减去。使用add esi, 2

【讨论】:

非常感谢。我会考虑到这一点。【参考方案2】:

哈德斯佩罗

您遇到了访问冲突,因为您试图写入数组边界。

几件事:

    您似乎没有初始化ecx。您应该将其初始化为数组的大小。 因为您是 cmp ecx,0,所以您应该在比较之前递减 ecx 在确保不会超出边界后,您应该移动esiaddress 调整。我将重组代码以测试 ecx 是否为零,如果为真则跳出,否则递减 esi 并跳回 ArrFill

【讨论】:

我包含了 ;using ecx as counter 这一行,专门用来引用我正在使用 ECX 的事实。我认为没有必要包含它,但现在我会包含它。

以上是关于运行循环时 MASM x86 访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

如何在 x86 汇编语言中创建嵌套循环

x86 MASM - 传递和访问二维数组

MASM x86 如何打印多行字符串变量?

汇编程序 MASM,当值为 0 或以下时在 JNZ 循环中打印

如何在程序集的循环内打印字符串(MASM)

vs2017下汇编环境配置