如何在汇编语言ARM中反转数组?

时间:2017-02-16 17:21:06

标签: arrays assembly arm reverse

(问题是基于汇编语言ARM。) 我处理的问题是要求我反转给定的数组。 就像这样:

       Given array: 1, 2, 3, 4, 5
       Reversed array: 5, 4, 3, 2, 1

这个问题的局限性在于我只能使用寄存器r0-r3。

我有一个基本的算法,但是当我试图实现这个想法时,我真的很困惑。 我的算法:

Loop:
      1. get value from head pointer, ptr++
      2. get value from tail pointer, ptr--
      3. swap them
      4. check if head pointer and tail pointer cross,
         if so, exit loop and return.
         if not, go back to loop.

但我不知道如何只使用4个寄存器来解决这个问题。

以下就是我目前的所有内容。

.text
.global reverse

reverse:
    @ See if head and tail ptr cross
    @ If so, end loop (b end)

head:
    @ use r2 to represent head value
    ldr r2,[r0]     @ r2 <-*data get the first value

tail:
    @ mov r1,r1     @ size
    sub r1,r1,#1    @ size-1
    lsl r1,r1,#2    @ (size-1)*4
    add r0,r0,r1    @ &data[size-1]      need to ldr r1,[r0] to get value
    ldr r1,[r0]     @ get value for r1 (from tail)

swap:
    @ swap values
    mov r3, r1      @store value to r3
    str r2, [r0] 
    @ head ptr ++
    @ tail ptr --
    @ back to reverse

end:
    @ loop ends

1 个答案:

答案 0 :(得分:1)

原油和低效的例子

.data
        Array:  .word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32,64,128,256,512
        .equ    len.Array,.-Array
.text
        .global main
main:
        nop

        sub sp, sp, #len.Array          // save space on stack 

        ldr r1,=Array                   // Array
        mov r2, #len.Array              // length of array
        mov r3, #0                      // zero init counter Array
        1:
                ldr r0, [r1,r3]         // load word size element position x from Array
                push {r0}               // push element value into stack 
        add r3, r3, #4                  // inc Array counter by 4 since word size is 4 bytes
        cmp r3, r2                      //
        blt 1b

        // pop values off the stack  - LIFO results in reversal

        mov r3, #0                      // zero init counter Array
        2:
                pop {r0}        // pop element value from stack -  LIFO
                str r0, [r1,r3]

        add r3, r3, #4                  // inc Array counter by 4 since word size is 4 bytes                                                                                                         cmp r3, r2
        blt 2b                                                                                                                                                                                                                                                                                                                                                                                    add sp, sp, #len.Array          // restore stack pointer

GDB输出:

(gdb) x/21d $r1
0x1102d:        1       2       3       4
0x1103d:        5       6       7       8
0x1104d:        9       10      11      12
0x1105d:        13      14      15      16
0x1106d:        32      64      128     256
0x1107d:        512


(gdb) x/21d $r1
0x1102d:        512     256     128     64
0x1103d:        32      16      15      14
0x1104d:        13      12      11      10
0x1105d:        9       8       7       6
0x1106d:        5       4       3       2
0x1107d:        1