This website is written in Ruby using the Sinatra framework and hosted with Passenger / Nginx on the Raspberry Pi ( temporarily not on a Pi! ) assisted by Cloudflare and a dash of jsDelivr

Adventures in Assembly

Always eager to use the Raspberry Pi as an excuse to push my knowledge of programming and hardware, I decided to go on a little journey into the mystifying world of ARM Assembly.

Following the guide from http://savannah.nongnu.org/projects/pgubook/ I set about rewriting the Intel? Assembly in the examples to the ARM equivilent. I had some difficulty accessing the array of numbers in the find-the-largest-number example, but eventually overcame it with sheer determination and a lot of fumbling through any references to ARM assembly I could turn up on Google. The resulting, not exactly brilliant, code with amends suggested by Tufty is as follows:

.data
    data_items:
    .long 3,67,34,222,45,75,54,245,34,44,33,22,11,66,0

    msg:
    .ascii "Finding Largest Number\n"
len = . - msg

.text
    .code 32
    .globl _start

_start:

    mov     r0, #0x000001	@ Not sure why we put a 1 here
    ldr     r1, =msg		@ Put the msg address in r1
    ldr     r2, =len		@ And the len in r1
    mov     r7, #0x000004	@ And the syscall for write in the r7
    svc     #0x000000

    ldr     r4,=data_items	@ Load address of data_items into r4
    mov     r5,#0x000000	@ Start our r5 counter at 0
    ldr     r0,[r4,r5,LSL #0x000002]@ Load from data_items r4 with offset r5 and multiplier of 2

start_loop:
    cmp     r1,#0x000000	@ Check for end of list 0
    beq     loop_exit		@ Exit if we've hit 0

    add     r5,r5,#0x000001	@ Increment our counter
    ldr     r1,[r4,r5,LSL #0x000002]@ Load the next data_items into r1

    cmp     r1,r0		@ Compare
    ble     start_loop		@ Branch to the start of our loop if less or equal
    
    mov     r0,r1		@ Move r1 to r0 if its greater
    
    b       start_loop		@ Loop!

loop_exit:
    mov     r1,#0x000000
    mov     r4,#0x000000
    mov     r5,#0x000000
    mov     r7,#0x000001	@ 1 is the syscall for exit
    svc     #0x000000

Building and running the file is fairly simple, excepting the cryptic CPU name which I retrieved from the forums thanks to tufty. Just run the following commands, assuming your code is in the file big.s:

as -g -mcpu=arm1176jzf-s -o big.o big.s
ld -o big big.o
./big
echo $?

That last line, echo $?, should display the exit code that big returned. In the above example, it'll be 245 because that's the largest number.

« Back to index Posted on 2012-06-20 by