MASM数组索引访问违规问题排查及数组元素修改求助
关于MASM中通过索引修改数组元素的问题
作业交换逻辑
array[0] = array[1] array[1] = array[0] array[2] = array[3] array[3] = array[2] ...
我编写的代码
.data ; add data here array01 DWORD 100, 200, 300, 400, 500, 600 var1 DWORD ? var2 DWORD ? .code main PROC mov edi, OFFSET array01 ; 1: EDI = address of array01 mov ecx, LENGTHOF array01 ; 2: initialize loop counter mov eax, 0 ; 3: sum =0 L1: ; 4: Mark beginning of loop mov eax, [edi] ; 5: Get var1 add edi, TYPE array01 ; 6: increment index mov ebx, [edi] ; 7: Get var2 sub edi, TYPE array01 ; 8: decrement to get index to point to the right location mov array01[edi], ebx ; 9: 执行此处时触发错误 add edi, TYPE array01 ; 10: increment index mov array01[edi], eax ; 11: Change array01[i] to var1 loop L1 ; 12: repeats until ecx is 0 INVOKE ExitProcess, 0 main ENDP End main
错误信息
Unhandled exception at 0x007C1032 in Assignment_03.exe: 0xC0000005: Access violation writing location 0x00F88004.
调试发现EDI的值是数组array01的起始地址(0x007C4000),但报错的写入地址是0x00F88004,明显越界。我知道mov dword ptr [array01], 700可以修改第一个元素,但用EDI索引就出错,不需要完整作业答案,只需要搞懂怎么正确通过索引修改数组元素。
核心问题解析
你出错的原因是对MASM的寻址语法理解有误:
- 执行
mov edi, OFFSET array01后,EDI中存储的是数组的绝对内存地址,不是相对于数组起始的偏移量 array01[edi]会被MASM解析为array01的起始地址 + EDI的值,相当于把数组起始地址再加一次自身地址,直接指向数组范围外的非法内存,这就是访问违规的根源
正确的两种索引修改方式
直接使用寄存器中的绝对地址
既然EDI已经指向数组元素的地址,直接用[edi]访问即可:mov [edi], ebx ; 写入EDI当前指向的数组元素对应你代码的第9行,应该改成
mov [edi], ebx,第11行改成mov [edi], eax使用数组名+偏移量
如果要保留数组名[寄存器]的写法,寄存器里必须存的是相对于数组起始的偏移值(比如从0开始的字节数):mov edi, 0 ; 初始偏移0,对应array01[0] mov array01[edi], ebx ; 正确:array01起始地址+0,指向第一个元素 add edi, TYPE array01 ; 偏移增加4(DWORD类型占4字节),指向array01[1]
内容的提问来源于stack exchange,提问作者Funlamb
相关产品推荐
相关产品推荐

