Daveedo
Daveedo

Reputation: 172

How to reverse an array in assembly language ARM?

(The problem is based on assembly language ARM.) I'm dealing with a problem which asking me to reverse a given array. Just like this:

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

And the limitation of this problem is that I'm only supposed to use registers r0-r3.

I have a basic algorithm, but I'm really confused when I'm trying to implement the idea. My algorithm:

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.

But I just don't know how to use only 4 registers to solve this problem..

Below would be all I have currently.

.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

Upvotes: 0

Views: 5327

Answers (1)

InfinitelyManic
InfinitelyManic

Reputation: 822

Crude and inefficient example

.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 output:

(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

Upvotes: 1

Related Questions