汇编冒泡排序代码出现Access violation writing location错误求助
冒泡排序访问违例问题修复
你的代码出现“Access violation writing location”错误的核心原因是数组索引越界,根源在于外层循环中ebx的计算逻辑错误,导致内层循环的计数器ecx在后续循环中变成负数(被loop指令当作超大无符号数处理),最终让esi超出数组范围访问非法内存。
问题细节
初始时ebx = LENGTHOF arr - 1 = 4,但每次进入外层l1循环时,你直接执行sub ebx, edx,而没有重置ebx的初始值。随着edx每次加1,ebx会被持续递减:
- 第1次外层循环:
ebx = 4 - 0 = 4(正常) - 第2次外层循环:
ebx = 4 - 1 = 3(正常) - 第3次外层循环:
ebx = 3 - 2 = 1(正常) - 第4次外层循环:
ebx = 1 - 3 = -2(异常)
此时ecx = ebx = -2,loop指令会将ecx视为无符号整数(值为0xFFFFFFFE),内层l2循环会疯狂执行,esi不断累加TYPE arr(4字节),最终超出数组的内存范围,触发访问违例。
修复方案
每次进入外层循环时,重新计算ebx为(LENGTHOF arr - 1) - edx,而不是在旧值上递减。修改后的代码如下:
INCLUDE irvine32.inc .data arr DWORD 8, 5,1,2,6 .code main PROC mov ecx, LENGTHOF arr sub ecx, 1 ; 外层循环次数:n-1 mov edx, 0 l1: push ecx ; 每次重新计算内层循环次数:(n-1) - edx mov ebx, LENGTHOF arr sub ebx, 1 sub ebx, edx mov ecx, ebx mov esi, 0 l2: mov eax, arr[esi] mov edi, arr[esi + TYPE arr] cmp edi, eax jle swap jmp done swap: mov arr[esi + TYPE arr], eax mov arr[esi], edi done: add esi, TYPE arr loop l2 pop ecx add edx, 1 loop l1 exit main endp end main
额外优化建议
- 冒泡排序可以加入是否发生交换的标记,如果某轮内层循环没有交换元素,说明数组已经有序,可以提前终止循环,提升效率。
- 变量命名可以更直观,比如用
outer_loop代替l1,inner_loop代替l2,便于维护。
内容的提问来源于stack exchange,提问作者k224058 Syed Ali Ahmed
相关产品推荐
相关产品推荐

