ARM 汇编器常规冒泡排序 [英] ARM Assembler Regular Bubble Sort

查看:42
本文介绍了ARM 汇编器常规冒泡排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试根据给定的 C 冒泡排序代码在 ARM 汇编程序中编写一个简单的冒泡排序:

I tried to write a simple bubblesort in ARM Assembler on a basis of a given C bubblesort code:

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);
}

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

And here is my assembler code I wrote so far:

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).将内存中的值加载到寄存器中,比较它们,然后交换寄存器中的值并将它们存储到内存中的正确位置.

My goal is to sort a sequence of ints or an "array". Given parameters are the address of the first value (r0) and the table size (r1). Load the values from the memory into registers, comparing them, then swap the values in the registers and store them at the right position into the memory.

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

Before I changed my code I ran the debugger, the "swapping" part in the registers seems to work fine. But im not too sure about the loop-logic I did there. My problem is, when I take a look into the memory, the first value is correctly sorted and then it just stops sorting / ignores the rest.

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

Now all I get is an endless loop.

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

I will greatly appreciate any given help.

另外,如果有什么我忘了提,请告诉我,我会提供的.

Also if there is anything I forgot mentioning, just let me know and I will provide it.

提前致谢,

德特

推荐答案

@ ---- 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 将表指针移动到下一个位置.

Your code logic is good. I have added several sections to compile and run it, which is marked in your code. Two things to note, mov r4, #1 to start the count, and add r0, #4 to move the table pointer to the next position.

我还将包含我的调试脚本,这些脚本有助于发现错误并帮助理解交换开关(通过将 -128 更改为 128,减少循环次数).

I will also include my debugging scripts that helped with finding errors and help to understand the swap switch (by changing the -128 to 128, less passes through the loops).

@ ---- 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<
"  @ 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 $?,以@"开头的行是我对它们下面的寄存器的标题注释.

The output from ./bubblesort2; echo $?, the lines that start with "@" are my heading comments for the registers below them.

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

这篇关于ARM 汇编器常规冒泡排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆