如何修复C++调用汇编程序时出现的访问违反(Access Violation)异常
访问违例报错排查与修复
直接触发异常的核心原因
你编写的汇编代码最后执行了pop ebp,但整个函数内没有对应的push ebp操作,导致栈结构被破坏,ret指令读取到错误的返回地址,跳转到了不可执行的内存区域,直接触发0xC0000005访问违例。
其余需修复的逻辑错误
- 元素数量定义错误:C++参考代码中数组长度为4,你汇编里
numElements赋值为5,会导致数组越界访问 - 完全缺失循环逻辑:现有代码判断完第一个元素后直接跳转到结束位置,没有遍历整个数组,也没有递增数组指针、递减循环计数器的逻辑
- 判断条件完全不匹配:C++要求同时满足
index >= 1、当前数组元素 > 2两个条件才执行乘法,现有判断逻辑完全不符合需求 - 乘法指令使用错误:
mul numberArray只会取数组第一个元素做乘法,且32位mul指令默认与eax相乘后结果存入edx:eax,针对有符号整数乘法应该用imul更适配 - 寄存器未符合调用约定:x86 32位C调用约定中
ebx是被调用者需要保存的寄存器,修改前需要压栈保存,返回前要恢复原值,否则会导致C++调用方运行异常
修复后的完整汇编代码
.model flat, c .data numberArray DWORD 1, -3, 12, 15 numElements DWORD 4 .code problem1_ proc push ebp mov ebp, esp push ebx ; 保存被调用者需保留的ebx寄存器 mov eax, 0 ; eax存result,初始为0 mov edx, 0 ; edx存index,初始为0 lea ebx, numberArray ; ebx存数组首地址 mov ecx, numElements ; ecx存元素总数 iterateThruArray: cmp edx, ecx ; 比较index和总元素数 jge FINISH ; index >= 总数就退出循环 ; 先判断index >= 1 cmp edx, 1 jl else_block ; index <1 直接走else ; 再判断当前元素 >2 cmp [ebx + edx*4], 2 jle else_block ; 元素 <=2 走else ; 满足两个条件:result *= 当前元素 imul eax, [ebx + edx*4] jmp loop_end else_block: sub eax, 5 ; 不满足条件:result -=5 loop_end: inc edx ; index++ jmp iterateThruArray FINISH: pop ebx ; 恢复ebx原值 mov esp, ebp pop ebp ; 平衡栈帧 ret problem1_ endp end
运行验证
修复后代码运行结果为**-15**,和C++参考代码运行结果完全一致,不会再触发访问违例异常。
内容的提问来源于stack exchange,提问作者SaltandSorrow
相关产品推荐
相关产品推荐

