sorting - x86 尝试进行冒泡排序时出现段错误

标签 sorting assembly x86 bubble-sort

我正在尝试在汇编中实现冒泡排序。这是我的代码。我不断遇到段错误。我在下面有一个函数。我一直在尝试解决这个问题,但找不到 x86 的编译器,并且我一直在检查我的代码以检查问题所在,但无济于事。

这是我的函数代码:

bubble:
    push ebp
    mov ebp, esp

    push ecx
    push edx
    push edi
    push esi
    push ebx
    push eax
    
   
    mov eax, 0
    mov ecx, [ebp+12] ; number of elements in the array
    mov edx, [ebp+8]; address of array
    mov edi, 0
    mov esi, 0
    dec ecx; n - 1

    mov esi, 1

    sortOuter:
        cmp esi, 0
        jg sort

        sort:

        mov esi, 0 ;count

        check:
        cmp edi, ecx ; i < n - 1
        jl sortInner

        sortInner:
            mov ebx, [edx+edi*4] ; mov array[i+1] to ebx
            cmp [edx], ebx   ; cmp array[i] to array[i+1]
            jle noswap

            swap:
                mov eax, ebx ; mov array[i+1] to eax
                mov ebx, [edx] ; mov array[i] to array[i+1]
                mov [edx], eax ; mov array[i+1] to array[i]
                
                inc esi ; count++

            noswap:

            inc edi ; i++
            jmp check
    
        
        jmp sortOuter

    done:


    call print_nl


    pop ebx
    pop esi
    pop edi
    pop edx
    pop ecx

    
    mov esp, ebp
    pop ebp
    ret

最佳答案

段错误来自您创建的无限循环

check:
  cmp edi, ecx ; i < n - 1
  jl sortInner

  sortInner:

如果 EDI 小于 ECX,您将跳转到 sortInner,但如果不是,您将进入 sortInner。无论如何,您最终总是在 sortInner 处运行代码,并且由于代码使用的内存地址不断增长,在某些时候您将尝试读取您无权访问的内存,因此出现段错误。

现在,如果您要纠正此问题,则会有第二个无限循环等待。

sortOuter:
  cmp esi, 0
  jg sort

  sort:

其他错误包括:

  • 在内循环开始时重置 ESI 而不是 EDI
  • 根本不交换元素,但总是在第一个数组元素中写入最小值
  • 忘记恢复寄存器EAX

这是一个正在运行的冒泡排序。不要只是复制它,而是要了解它是如何运作的!

在具有 N 个元素的数组中,我们最多必须进行 N-1 次比较(以使最大值朝后冒泡)。
因为 InnerLoop 使用的计数器是从不断递减的 OuterLoop 计数器初始化的,因此 OuterLoop 的每次迭代都会占用数组的一部分InnerLoop 中处理的数据变得更小。然后我们不再处理的数组部分包含已向数组末尾冒泡的最大元素,因此得名“BubbleSort”。
已针对空数组或只有 1 个元素的数组做出了规定。始终包含一些特殊情况的代码!

bubble:
  push ebp
  mov  ebp, esp
  push ...

  mov  ecx, [ebp + 12] ; Number of elements in the array
  sub  ecx, 1          ; First time we do n = N-1
  jbe  Done            ; Array is empty or has but 1 element

OuterLoop:
  mov  edx, ecx        ; Current value of the OuterLoop counter (n)
  mov  esi, [ebp + 8]  ; Address of array
InnerLoop:
  mov  eax, [esi]
  mov  ebx, [esi + 4]
  cmp  eax, ebx
  jng  NoSwap
  mov  [esi], ebx
  mov  [esi + 4], eax
NoSwap:
  add  esi, 4
  dec  edx
  jnz  InnerLoop
  dec  ecx                ; Next times we do n = n-1
  jnz  OuterLoop

Done:
  pop  ...
  pop  ebp
  ret

关于sorting - x86 尝试进行冒泡排序时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74487829/

相关文章:

javascript - 按特定键对对象数组进行排序

c++ - 从德州仪器 C200 DSP 检索代码

c++ - 排序问题如何访问私有(private) vector 值

php - 如何以编程方式对查看结果进行排序?

assembly - 处理(可能)从JITed cod提前调用的编译函数的调用

assembly - 关于 AT&T x86 语法设计的问题

linux - 程序集:printf 不打印新行

assembly - NASM 中的 "push BYTE 0x80"和 "warning: signed byte value exceeds bounds"

iPhone:根据位置排序

c - GCC链接器不链接标准库