# ARM assembly - Fibonacci Implementation: PUSH and POP not working as expected

have written this ARM assembly code. It is supposed to put the Fibonacci sequence numbers in R4 register. I'm trying to implement this C code in assembly:

``````int fibbonacci(int n)
{
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return (fibbonacci(n-1) + fibbonacci(n-2));
}
``````

This is the assembly code I have written:

``````                   AREA |.text|, CODE, READONLY
EXPORT Fib
Fib
;R0(n) - store the first n numbers in the Fibonacci sequence
;R1    - address of the first element in the array to store the Fibonacci sequence
MOV      R4, #0
MOV      R5, #0
MOV      R6, #1

FiboR
CMP      R0, #1
PUSHEQ   {R5, R6, LR}
BEQ      Return
SUBS     R0, R0, #1
BL       FiboR
PUSH     {R4, R2, LR}
Return
POP      {R2, R3, PC}
ALIGN             END
``````

It is not behaving exactly like that posted C code so far because I need to keep working on it and make it return to main after it prints the first 5 numbers. However for now I need to fix something.

When my code reaches this line:

``````PUSH     {R4, R2, LR}
``````

It's supposed to push values R4, R2 and LR on the stack which at that moment are: 1, 0, LR. Then the code goes down into the 'Return' subroutine in which I'm doing this:

``````POP      {R2, R3, PC}
``````

So at this moment R2 should be loaded with value 1, R3 with value 0 and PC with value of LR so I return to this line:

``````ADD      R4, R2, R3
``````

The code does return to the ADD line however the value of R2 is not loaded with the value 1 as I expected it to. My code stays here in an infinite loop and I keep pushing {1, 0, LR} on the stack but when I try to pop these values into R2, R3 and PC apparently they are not getting popped as I would expect them to at least value 1 does not go into R2 and R2 keeps it's value of 0 forever.

Parents
• Multi-register PUSHES are always done in ascending register order, so what may LOOK like

`PUSH {R4,R2,LR}`

is actually

`PUSH {R2, R4, R14}`

so R2 is pushed first, to the highest stack address, and R14 (LR) is pushed last, to the lowest stack address.

Apply the reverse logic for POPs.

I imagine that is playing havoc with your logic ;)

• Multi-register PUSHES are always done in ascending register order, so what may LOOK like

`PUSH {R4,R2,LR}`

is actually

`PUSH {R2, R4, R14}`

so R2 is pushed first, to the highest stack address, and R14 (LR) is pushed last, to the lowest stack address.

Apply the reverse logic for POPs.

I imagine that is playing havoc with your logic ;)

Children
More questions in this forum

1860 views
0 replies
Started
by

1202 views
7 replies
Latest
by

240 views
0 replies
Started
by

18 views
0 replies
Started