This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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                          
    ADD      R4, R2, R3             
    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.

Can you please help me what am I missing here? Thank you for reading!

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 ;)

Reply
  • 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