Using Recursive Functions and Thumb Instructions to Calculate a Fibonacci Number
Solution
.data
/* numbers to use for the comparison */
Number1: .word 12
Number2: .word 43
Number3: .word 25
/* place to save largest number */
LargestNum: .word 0
.text
.globl main
main:
ldr r0, =Number1 /* load Number 1 address in r0 */
ldr r0, [r0] /* load first number into r0 */
ldr r1, =Number2 /* load Number 2 address in r1 */
ldr r1, [r1] /* load first number into r1 */
ldr r2, =Number3 /* load Number 3 address in r2 */
ldr r2, [r2] /* load first number into r2 */
BL largest /* Call function1 with the 3 numbers in r0, r1 and r2 */
ldr r0, =LargestNum /* load largestNum address in r0 */
str r4, [r0] /* save largest number in the largestNum variable */
done: B done
/* Function that gets the largest of 3 numbers passed in r0, r1 and r2
it returns the largest in r4 */
largest:
MOV r4, r0 /* load r0 in r4 */
CMP r4, r1 /* compare r4 with second number */
BGE compThird /* if r4 is larger, compare with 3rd */
MOV r4, r1 /* else, r1 was larger, save it in r4 */
compThird:
CMP r4, r2 /* compare r4 with third number */
BGE compDone /* if r4 is larger, r4 is the largest, we are done */
MOV r4, r2 /* else, r2 was the largest, save it in r4 */
compDone:
MOV pc, r14 /* return */
.data
/* number to use for the fibonacci */
fibinput: .word 16
/* place to save fibonacci result */
fibnumber: .word 0
.text
.globl main
main:
ldr r0, =fibinput /* load fibinput address in r0 */
ldr r0, [r0] /* load fibinput value into r0 */
BL fibonacci /* Call fibonacci with the number in fibinput */
ldr r1, =fibnumber /* load fibnum address in r1 */
str r0, [r1] /* save fibonacci result in the fibnum variable */
done: B done
/*Function that calculates the fibonacci number r0
it returns the result in r0 */
fibonacci:
STMFD SP!, {r4, r5, lr} /* save r4, r5 and lr in stack */
CMP r0, #0 /* compare number with 0 */
BGT NZ /* if neither zero nor negative, skip */
MOV r0, #0 /* else, return 0 */
B RETURN /* go to return part */
NZ: CMP r0, #1 /* compare number with 1 */
BEQ RETONE /* if it's 1, go to return one */
CMP r0, #2 /* compare number with 2 */
BEQ RETONE /* if it's 2, go to return one */
MOV r4, r0 /* save current number in r4 */
SUB r0, r0, #1 /* calculate number-1 */
BL fibonacci /* recurse to calculate fibonacci(n-1) */
MOV r5, r0 /* save result of fibonacci(n-1) in r5 */
MOV r0, r4 /* recover current number from r4 */
SUB r0, r0, #2 /* calculate number-2 */
BL fibonacci /* recurse to calculate fibonacci(n-2) */
ADD r0, r0, r5 /* add fibonacci(n-1) to fibonacci(n-2) */
B RETURN /* return value in r0 */
RETONE:
MOV r0, #1 /* put 1 in r0 for returning it */
RETURN:
LDMFD SP!, {r4, r5, lr} /* restore registers from stack */
MOV pc, lr /* return */