调用Irvine32的writeString时EDX传参触发访问违规错误如何解决?
错误原因排查
核心前提:Irvine32 writeString 调用规则
writeString 要求传入的 EDX 必须是以0(NULL字节)结尾的字符串的内存首地址,不能直接传入字符内容,也不能传入非法内存地址。
两段代码的具体错误
- 第一段代码错误:
mov edx, [esi + eax * 4]是取esi + eax*4地址处存储的4字节字符内容赋值给EDX,相当于把字符值当成内存地址传入函数,访问非法地址直接触发报错。 - 第二段代码错误:
第一次调用writeString时EDX确实是数组首地址,但是执行mov esi, [esi + 4]时,又是把esi指向的内存内容赋值给esi本身,第二次循环时esi已经是非法的字符值,再次调用writeString传入的EDX就是非法地址,触发访问违规。 - 额外逻辑问题:
即使地址正确,writeString会一直输出直到遇到NULL字节,不会自动只输出4个字符,也没有实现每4个换行的需求。
正确实现方案
这里采用单字符输出的方案实现「每4个字符换行」的需求,不需要处理字符串结尾逻辑,兼容性更强:
前提假设:
array1是BYTE类型的字符数组,totalSize为数组总字符数
mov esi, OFFSET array1 mov ebx, totalSize mov eax, 0 ; 全局计数器,记录已输出的字符总数 forLoop: cmp eax, ebx jae loopExit ; 所有字符输出完成,退出循环 ; 输出当前单个字符 mov al, [esi + eax] call WriteChar inc eax ; 判断是否到了4的倍数,是则输出换行 test eax, 3 ; 等价于 eax % 4 == 0 的判断,性能更高 jnz forLoop call Crlf ; 输出换行 jmp forLoop loopExit:
如果你的字符数组确实是按DWORD存储(每个元素存4个字符),可以调整步长每次取4个字符分别输出即可,核心逻辑和上面一致。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

