我正在尝试在汇编中实现冒泡排序。这是我的代码。我不断遇到段错误。我在下面有一个函数。我一直在尝试解决这个问题,但找不到 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/