这个 x86 汇编冒泡排序程序有啥问题?
Posted
技术标签:
【中文标题】这个 x86 汇编冒泡排序程序有啥问题?【英文标题】:What is wrong with this x86 assembly bubble sort program?这个 x86 汇编冒泡排序程序有什么问题? 【发布时间】:2019-05-30 16:26:21 【问题描述】:我需要弄清楚为什么在这个程序中什么都没有交换。该程序从一个单独的 C 程序中获取一个包含 4,5,1,3,2 的整数数组,并将其返回排序后。
我尝试修改了一些跳转命令,但没有任何效果。
.global myarray
.data
myarray:
lea (%rdi),%r8 #load array to register
mov %rsi,%r12 #load array size to register
mov $0,%r10 #initialize index
sort:
mov (%r8, %r10, 8), %rax #store array[i] in rax
inc %r10 #i++
mov (%r8, %r10, 8), %rdx #store array[i+1] in rdx
cmp %rax, %rdx #see if rdx is less than rax
jle swap #if rdx < rax, swap them
swap:
cmp %r12, %r10 #check if still in array bounds
je check #if we are at the end, check if sorted
dec %r10 #i--
mov %rdx, (%r8, %r10, 8) #move array[i+1] into array[i]
inc %r10 #i++
mov %rax, (%r8, %r10, 8) #move array[i] into array[i+1]
jmp check
check:
mov $0, %r14 #temporary index in r14
mov (%r8, %r10, 8), %eax #temporarily store array[i] in eax
inc %r14 #i++
mov (%r8, %r10, 8), %ebx #temporarily store array[i+1] in ebx
cmp %eax, %ebx #check if ebx is less than eax
jle sort #if ebx < eax, swap
cmp %r12, %r14 #check if still in array bounds
ret
预期结果是返回的数组排序; 1,2,3,4,5
【问题讨论】:
dec/inc
r10 围绕内存引用作为寻址模式的一部分的位移会更简单:-8(%r8, %r10, 8)
。简化代码的局部小部分可以使调试时更容易看到全局,而不会迷失在混乱中。 (使用 GDB 或任何其他调试器来单步执行您的代码。)
【参考方案1】:
mov %rsi,%r12 #load array size to register mov $0,%r10 #initialize index
在包含 5 个元素的数组中,您只能比较 4 对。减少%r12
会很方便。同时,当数组只有 1 个元素时,您将有一条出路:
mov %rsi,%r12 #load array size to register
dec %r12
jz NothingToDo
mov $0,%r10 #initialize index
cmp %rax, %rdx #see if rdx is less than rax jle swap #if rdx < rax, swap them swap:
如果 LessOrEqual 跳转到 swap,否则代码在 swap 中通过。这毫无意义!
下面是使最大数字冒泡到顶部的代码。
sort:
mov (%r8, %r10, 8), %rax #store array[i] in rax
inc %r10 #i++
mov (%r8, %r10, 8), %rdx #store array[i+1] in rdx
cmp %rdx, %rax
jle NoSwap
dec %r10 #i--
mov %rdx, (%r8, %r10, 8) #move array[i+1] into array[i]
inc %r10 #i++
mov %rax, (%r8, %r10, 8) #move array[i] into array[i+1]
NoSwap:
cmp %r12, %r10 #check if still in array bounds
jb sort
此内部循环代码必须重复多次,但每次您降低%r12
中的限制。 (*)
jmp check check:
这也是个没用的jmp
!
check: mov $0, %r14 #temporary index in r14 mov (%r8, %r10, 8), %eax #temporarily store array[i] in eax inc %r14 #i++ mov (%r8, %r10, 8), %ebx #temporarily store array[i+1] in ebx cmp %eax, %ebx #check if ebx is less than eax jle sort #if ebx < eax, swap cmp %r12, %r14 #check if still in array bounds
而且这部分代码无法挽救。这里发生的事情令人无法理解。
(*)
mov %rdi,%r8
mov %rsi,%r12
dec %r12
jz NothingToDo
OuterLoop:
mov $0,%r10
...
dec %r12
jnz OuterLoop
NothingToDo:
ret
【讨论】:
以上是关于这个 x86 汇编冒泡排序程序有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章