x86汇编实现冒泡排序触发Segmentation Fault问题求助
x86汇编冒泡排序段错误排查
以下是你的代码中导致段错误及逻辑错误的核心问题:
寄存器栈平衡错误:你入栈的顺序是
push ecx→push edx→push edi→push esi→push ebx→push eax,但出栈时顺序是pop ebx→pop esi→pop edi→pop edx→pop ecx,遗漏了对eax的出栈操作。栈的后进先出特性会导致栈顶数据被错误弹出,最终ret指令会获取到错误的返回地址,直接触发段错误。数组访问逻辑错误:
- 你在
sortInner中用mov ebx, [edx+edi*4]标注取array[i+1],但实际计算的是array[i]的地址(数组基址+索引i*4字节); - 后续
cmp [edx], ebx是拿array[0]和当前元素比较,而非冒泡排序需要的相邻元素对比,正确的应该是对比[edx+edi*4](array[i])和[edx+(edi+1)*4](array[i+1])。
- 你在
循环控制逻辑混乱,导致无限越界访问:
- 内层循环结束后,
edi没有重置为0,随着外层循环重复,edi会持续递增,远超数组元素数量,访问非法内存触发段错误; - 外层循环的终止逻辑完全错误:
sortOuter中的cmp esi, 0→jg sort逻辑颠倒,且没有跳转到done的分支,导致程序陷入无限循环,最终必然触发内存越界。
- 内层循环结束后,
交换逻辑错误:当前交换代码只修改了
array[0]和某个元素的值,而非相邻的array[i]和array[i+1],完全不符合冒泡排序的交换逻辑。
修正后的核心逻辑示例
bubble: push ebp mov ebp, esp ; 寄存器入栈(保持顺序统一) push eax push ebx push ecx push edx push esi push edi mov ecx, [ebp+12] ; 元素个数n dec ecx ; n-1,内层循环最大索引 mov edx, [ebp+8] ; 数组基址 outer_loop: mov esi, 0 ; 交换计数器,初始为0 mov edi, 0 ; 内层循环索引i,每次外层重置为0 inner_loop: ; 取array[i]和array[i+1] mov eax, [edx+edi*4] mov ebx, [edx+(edi+1)*4] cmp eax, ebx jle no_swap ; 前<=后,不交换 ; 交换array[i]和array[i+1] mov [edx+edi*4], ebx mov [edx+(edi+1)*4], eax inc esi ; 交换计数+1 no_swap: inc edi cmp edi, ecx ; i < n-1? jl inner_loop cmp esi, 0 ; 本次外层无交换,说明已排序完成 jne outer_loop ; 有交换则继续外层循环 done: call print_nl ; 寄存器出栈(和入栈顺序相反) pop edi pop esi pop edx pop ecx pop ebx pop eax mov esp, ebp pop ebp ret
内容的提问来源于stack exchange,提问作者Rheagar
相关产品推荐
相关产品推荐

