You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:01:31