0

Ok, I am trying to implement the selection sort algorithm in ARM7 Assembly. It starts with last element of array and works its way down to first element. It works for the first swap, but then exits before continuing on. I talked to my professor and he said to use the stack variables so that the lr doesnt get overwritten etc, but I still dont understand exactly how to do that. Ive searched for ways to do this, but cant seem to find anything that I understand how to implement in my code.

My code is as follows: (a1 is pointer to char array of length a2. Both are passed in via C)

sort2:
    stmdb    sp!, {v1-v8, lr}          @ Copy registers to stack
    mov      v1, a2                    @store number of elements in v1,v2 (a2 is passed in via C)
    mov      v2, a2
    sub      v1, v1,#1                 @subtract 1 from a2 to get number last element in array
    sub      v2, v1,#1                 @subtract 1 from v1 to get element just below last element
    bl       loop2
    ldmia    sp!, {v1-v8, pc}

loop2:
    ldrb     v4, [a1,v1]               @store value of last element in array a1(passed in via C) into r4 
    ldrb     v5, [a1,v2]               @store value of next to last element in array a1(passed in via C) into r4 
    cmp      v4, v5
    blt      swap2                     @if last element is less than current element a[v2], swap them
    cmp      v2, #0                    @if v2 = 0, we cycled through one iteration
    subeq    v1, v1,#1                 @so now move on to a[v1-1] element in array                   
    moveq    v2, v1                    @if v2 = 0, move the value of v1 into v2
    sub      v2, v2,#1                 @subtract 1 from v2 to get element below a[v1]
    cmp      v1, #0                    @if v1 = 0, were done
    bne      loop2
    mov      pc, lr                    @return to sort2

swap2:
    mov      v8, lr                    @store return address in v8
    ldrb     v6, [a1,v2]               @store value of a[v2] into v6
    strb     v4, [a1,v2]               @store v4 into a[v2]
    strb     v6, [a1,v1]               @store value of v6 into a[v1]
    mov      lr, v8                    @falls through and exits here instead of returning to loop2
vt-cwalker
  • 795
  • 2
  • 16
  • 34

1 Answers1

1

There are already a couple of places where you return from a subroutine.

When you enter sort2, you save some registers on the stack:

stmdb    sp!, {v1-v8, lr}          @ Copy registers to stack

And when you leave sort2, you restore some registers from the stack:

ldmia    sp!, {v1-v8, pc}

When you leave loop2, you do something similar:

mov      pc, lr                    @return to sort2

Look closely at that. Notice a pattern there? Leaving swap2 should have something similar.

Now, loop2 supposedly calls another function: swap2. To support calling other functions, the calling function should save some registers, just as sort2 does. Leaf functions (functions which do not call other functions) don't need to save caller-saved registers. Also, as @PeteFordham's deleted answer points out: blt = branch on less than; bllt = branch and link on less than.

ninjalj
  • 42,493
  • 9
  • 106
  • 148
  • So I need to add `stmdb sp!, {v1-v8, lr}` to `loop2` before the `blt` call (and switch `blt to bllt`)? and then have a `mov pc, lr` at end of `swap2`? – vt-cwalker Nov 16 '12 at 02:31