Search code examples
sortingassemblyavrbubble-sort

Is this assembly code sorting numbers in ascending order?


I am trying to figure out what this assembly code is performing.

.equ        SIZE    =128
.equ        TABLE_L =$60
.equ        TABLE_H =$00

.def    A   =r13
.def    B   =r14
.def    cnt2    =r15
.def    cnt1    =r16
.def    endL    =r17
.def    endH    =r18

Outer:
    mov ZL, endL
    mov ZH, endH
    mov cnt2, cnt1
inner_loop: ld  A, Z
    ld  B, -Z
    cp  A, B
    brlo    L1
    st  Z, A
    std Z+1, B
L1: dec cnt2
    brne    inner_loop
    dec cnt1
    brne    Outer
    ret

table:  

I believe it may be sorting numbers in ascending order, but I am not sure. The table is left blank as I am not sure what values are stored there. I am trying to figure out what the code does based only on the code.


Solution

  • Yeah, looks like a simple Bubble Sort (without the "early out" optimization that bloats the code by checking if any swaps have happened; if you want better almost-sorted-input performance, use InsertionSort). See Bubble Sort: An Archaeological Algorithmic Analysis for a look at different forms of Bubble Sort, including this where the range of elements scanned decreases by 1 each outer iteration.

    It has an interesting advantage for code-size on AVR vs. other simple sort, which is that the accesses are all local so they can all use the Z register, and don't have to do add-with-carry for address calculation. (Although Insertion Sort should be similar.)


    A is loaded from the higher address.

    cp A,B / brlo skips the swap if the unsigned lower element is already at the higher address, so it's sorting the lowest (unsigned) elements to the end of the array. That's descending order.

    The stores (if they happen) are to the same two locations the loads were from, so this is indeed a swap, not some buggy nonsense.