这个x86程序集冒泡排序程序有什么问题?

时间:2019-05-30 16:26:22

标签: assembly x86 att

我需要弄清楚为什么此程序中什么都没有交换。该程序从一个单独的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

1 个答案:

答案 0 :(得分:0)

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