ARM汇编程序常规冒泡排序

时间:2016-06-02 16:24:03

标签: assembly arm

我尝试在给定的C bubblesort代码的基础上在ARM Assembler中编写一个简单的bubblesort:

bubbleSort (int A[], int n)
{
    int temp;
    int i;
    do {
        swapped = false;
        n = n-1;
        for (i=0; i < n; i++) {
            if ( A[i] > A[i+1] ) {
                temp = A[i];
                A[i] = A[i+1];
                A[i+1] = temp;
                swapped = true;
            }
        }
   } while (swapped == true);
}

这是我到目前为止编写的汇编代码:

bubblesort:
      @ maybe r0, r1 for table and counter (rest is based on that)
      @ r8 = Buffer for Value
      @ r4 = Counter for loop1
      @ r5 = Register for Value
      @ r7 = Register for Value
      @ r1 = Size of Array
      @ r0 = Address of the 1. Element
      @ r10 = "swapped" register



loop:
     mov r10, #0
     sub r1, #1            @ Decrement Counter for loop



     loop1:

            ldr r5, [r0]
            ldr r7, [r0, #4]


            cmp r5, r7

                  movgt r8, r7
                  movgt r7, r5
                  movgt r5, r8
                  strgt r5, [r0]
                  strgt r7, [r0, #4]
                  movgt r10, #1




            cmp r4, r1   @ compare r4 and r1
            add r4, #1   @ Increment counter for loop1
            blt loop1    @ is r4 < r1 ? yes = go to loop1


     cmp r10, #1
     beq loop

我的目标是对一系列整数或“数组”进行排序。给定参数是第一个值(r0)和表大小(r1)的地址。 将存储器中的值加载到寄存器中,进行比较,然后交换寄存器中的值并将它们存储在存储器中。

之前我改变了我的代码我运行了调试器,寄存器中的“交换”部分似乎工作正常。但我不太确定我在那里做的循环逻辑。 我的问题是,当我查看内存时,第一个值被正确排序,然后它就会停止排序/忽略其余值。

现在我得到的是一个无限循环。

我将非常感谢任何给定的帮助。

如果有什么我忘记提及的,请告诉我,我会提供。

提前致谢,

与Dethe

1 个答案:

答案 0 :(得分:0)

@ ---- Added ----
@ bubblesort.s
@
@ pi@RPi3:~ $ as -o bubblesort.o bubblesort.s
@ pi@RPi3:~ $ gcc -o bubblesort bubblesort.o
@ pi@RPi3:~ $ ./bubblesort; echo $?

.data

table:
  .word 9, -8, -7, 6, -5, 4, -3, 2, -1, 0, 127, -128
aft_table:

.balign 4
n:
  .word (aft_table - table) >>2

.text
.global main
main:
     push  {r4-r10, lr}
     ldr   r1, =n
     ldr   r1, [r1]       @ len(table) in r1
@ ---------------

bubblesort:
      @ maybe r0, r1 for table and counter (rest is based on that)
      @ r8 = Buffer for Value
      @ r4 = Counter for loop1
      @ r5 = Register for Value
      @ r7 = Register for Value
      @ r1 = Size of Array
      @ r0 = Address of the 1. Element
      @ r10 = "swapped" register

loop:
     mov r10, #0
     sub r1, #1            @ Decrement Counter for loop

@ ---- Added ----
   ldr   r0, =table
   mov   r4, #1      @ i = 1   i could = 0, if instructions
                     @ cmp r4, r1   @ compare r4 and r1
                     @ add r4, #1   @ Increment counter for loop1
                     @ were reversed
@ ---------------

     loop1:

            ldr r5, [r0]
            ldr r7, [r0, #4]

            cmp r5, r7

                  movgt r8, r7
                  movgt r7, r5
                  movgt r5, r8
                  strgt r5, [r0]
                  strgt r7, [r0, #4]
                  movgt r10, #1

@ ---- Added ----
                  add   r0, #4   @ Index table to next position
@ ---------------

            cmp r4, r1   @ compare r4 and r1
            add r4, #1   @ Increment counter for loop1
            blt loop1    @ is r4 < r1 ? yes = go to loop1

     cmp r10, #1
     beq loop

@ ---- Added ----
exit:
   pop   {r4-r10, lr}
   mov   r0, #0         @ good return code
   bx    lr             @ Exit with gcc linker
@ ---------------

您的代码逻辑很好。我已经添加了几个部分来编译和运行它,它在您的代码中标记。需要注意两件事,mov r4, #1开始计数,add r0, #4将表格指针移动到下一个位置。

我还将包括我的调试脚本,这些脚本有助于查找错误并帮助理解交换开关(通过将-128更改为128,更少通过循环)。

@ ---- Added ----
@ bubblesort2.s
@
@ pi@RPi3:~ $ as -o bubblesort2.o bubblesort2.s
@ pi@RPi3:~ $ gcc -o bubblesort2 bubblesort2.o
@ pi@RPi3:~ $ ./bubblesort2; echo $?

.data

table:
  .word 9, -8, -7, 6, -5, 4, -3, 2, -1, 0, 127, 128
aft_table:

.balign 4
n:
  .word (aft_table - table) >>2
@ ---------------

@ ---- Added ----
.balign 4             @ Prt
frmt:                 @ Prt
  .asciz "%d  "       @ Prt

.balign 4
flags:                @ RDmp
  .word 0             @ RDmp
msg:                  @ RDmp
  .asciz "NZCV  2> 6= 8<\n"  @ RDmp
aft_msg:              @ RDmp
                      @ RDmp
l_msg:                @ RDmp
  .word (aft_msg - msg) - 1  @ RDmp
@ ---------------

.text
.global main
.global printf, putchar  @ Prt
main:
     push  {r4-r10, lr}
     ldr   r1, =n
     ldr   r1, [r1]       @ len(table) in r1
     bl    Print          @ Prt
@ ---------------

bubblesort:
      @ maybe r0, r1 for table and counter (rest is based on that)
      @ r8 = Buffer for Value
      @ r4 = Counter for loop1
      @ r5 = Register for Value
      @ r7 = Register for Value
      @ r1 = Size of Array
      @ r0 = Address of the 1. Element
      @ r10 = "swapped" register

loop:
     mov r10, #0
     sub r1, #1            @ Decrement Counter for loop

@ ---- Added ----

   ldr   r0, =table
   mov   r4, #1      @ i = 1   i could = 0, if instructions
                     @ cmp r4, r1   @ compare r4 and r1
                     @ add r4, #1   @ Increment counter for loop1
                     @ were reversed
@ ---------------

     loop1:

            ldr r5, [r0]
            ldr r7, [r0, #4]

            cmp r5, r7

                  movgt r8, r7
                  movgt r7, r5
                  movgt r5, r8
                  strgt r5, [r0]
                  strgt r7, [r0, #4]
                  movgt r10, #1

@ ---- Added ----
                  add   r0, #4   @ Index table to next position
@ ---------------

            cmp r4, r1   @ compare r4 and r1
            add r4, #1   @ Increment counter for loop1
            blt loop1    @ is r4 < r1 ? yes = go to loop1

@ ---- Added ----
     bl    Print         @ Prt
     bl    RDmp          @ RDmp
@ ---------------

     cmp r10, #1
     beq loop

@ ---- Added ----

exit:
   pop   {r4-r10, lr}
   mov   r0, #0         @ good return code
   bx    lr             @ Exit with gcc linker

@ ---------------

@ ---- Added ----

 Print:                  @ Prt, table to stdout
    push  {r0-r10, lr}   @ Prt
    mrs   r10, cpsr      @ Prt
    ldr   r2, =n         @ Prt
    ldr   r2, [r2]       @ Prt
    ldr   r3, =table     @ Prt
 lp:                     @ Prt
    ldr   r0, =frmt      @ Prt
    ldr   r1, [r3], #4   @ Prt
    push  {r0-r3}        @ Prt
    bl    printf         @ Prt
    pop   {r0-r3}        @ Prt
    subs  r2, #1         @ Prt
    bne   lp             @ Prt
    mov   r0, #0xa       @ Prt
    bl    putchar        @ Prt
    msr   cpsr_f, r10    @ Prt
    pop   {r0-r10, lr}   @ Prt
    mov   pc, lr         @ Prt
@ ---------------

@ ---- Added ----
RDmp:                   @ RDmp
   push   {r0-r10, lr}  @ RDmp
   mrs    r10, cpsr     @ RDmp
   push   {r8-r11}      @ RDmp
   push   {r4-r7}       @ RDmp
   push   {r0-r3}       @ RDmp
                        @ RDmp
   ldr    r1, =flags    @ RDmp
   mrs    r0, cpsr      @ RDmp
   str    r0, [r1]      @ RDmp
   b      seq           @ RDmp
                        @ RDmp
p_char:                 @ RDmp
   push   {r0-r4, lr}   @ RDmp
   bl     putchar       @ RDmp
   pop    {r0-r4, lr}   @ RDmp
   mov    pc, lr        @ RDmp
                        @ RDmp
register:               @ RDmp
   mov    r1, #0        @ RDmp
   push   {r0, lr}      @ RDmp
                        @ RDmp
nibble:                 @ RDmp
   mov    r2, r3        @ RDmp
   lsl    r2, r1        @ RDmp
   lsr    r2, #28       @ RDmp
   add    r2, #48       @ RDmp
   cmp    r2, #58       @ RDmp
   addge  r2, #39       @ RDmp
   mov    r0, r2        @ RDmp
   bl     p_char        @ RDmp
   add    r1, #4        @ RDmp
   cmp    r1, #32       @ RDmp
   blt    nibble        @ RDmp
   mov    r0, #32       @ RDmp
   bl     p_char        @ RDmp
   pop    {r0, lr}      @ RDmp
   mov    pc, lr        @ RDmp
                        @ RDmp
manage:                 @ RDmp
   push   {r0, lr}      @ RDmp
   mov    r3, r4        @ RDmp
   bl     register      @ RDmp
   mov    r3, r5        @ RDmp
   bl     register      @ RDmp
   mov    r3, r6        @ RDmp
   bl     register      @ RDmp
   mov    r3, r7        @ RDmp
   bl     register      @ RDmp
   pop    {r0, lr}      @ RDmp
   mov    pc, lr        @ RDmp
                        @ RDmp
seq:                    @ RDmp
   pop    {r4-r7}       @ RDmp
   bl     manage        @ RDmp
   mov    r0, #32       @ RDmp
   bl     p_char        @ RDmp
   pop    {r4-r7}       @ RDmp
   bl     manage        @ RDmp
   mov    r0, #0x0a     @ RDmp
   bl     p_char        @ RDmp
                        @ RDmp
   pop    {r4-r7}       @ RDmp
   bl     manage        @ RDmp
   mov    r0, #32       @ RDmp
   bl     p_char        @ RDmp
   ldr    r3, =flags    @ RDmp
   ldr    r3, [r3]      @ RDmp
   bl     register      @ RDmp
                        @ RDmp
   ldr    r2, = l_msg   @ RDmp
   ldr    r2, [r2]      @ RDmp
   ldr    r1, =msg      @ RDmp
w_msg:                  @ RDmp
   ldr    r0, [r1], #1  @ RDmp
   bl     p_char        @ RDmp
   subs   r2, #1        @ RDmp
   bgt    w_msg         @ RDmp
   msr    cpsr_f, r10   @ RDmp
   pop    {r0-r10, lr}  @ RDmp
   mov    pc, lr        @ RDmp
@ ---------------

./bubblesort2; echo $?的输出,以“@”开头的行是我对其下方寄存器的标题注释。

9  -8  -7  6  -5  4  -3  2  -1  0  127  128  
-8  -7  6  -5  4  -3  2  -1  0  9  127  128  
@ (r0)     (r1)     (r2)     (r3)      (r4)     (r5)     (r6)     (r7)
000207f0 0000000b 7ee7077c 00010450  0000000c 0000007f 00010328 00000080 
@ (r8)     (r9)     (r10)    (r11)  (F)(cpsr) (F)   (F val)
00000000 00000000 60000010 00000000  60000010 NZCV  2> 6= 8<
-8  -7  -5  4  -3  2  -1  0  6  9  127  128  
000207ec 0000000a 7ee7077c 00010450  0000000b 00000009 00010328 0000007f 
00000000 00000000 60000010 00000000  60000010 NZCV  2> 6= 8<
-8  -7  -5  -3  2  -1  0  4  6  9  127  128  
000207e8 00000009 7ee7077c 00010450  0000000a 00000006 00010328 00000009 
00000000 00000000 60000010 00000000  60000010 NZCV  2> 6= 8<
-8  -7  -5  -3  -1  0  2  4  6  9  127  128  
000207e4 00000008 7ee7077c 00010450  00000009 00000004 00010328 00000006 
00000000 00000000 60000010 00000000  60000010 NZCV  2> 6= 8<
-8  -7  -5  -3  -1  0  2  4  6  9  127  128  
000207e0 00000007 7ee7077c 00010450  00000008 00000002 00010328 00000004 
00000000 00000000 60000010 00000000  60000010 NZCV  2> 6= 8<
0