fib_stack.s - A recursive subroutine example using the stack to compute a Fibonnachi numberΒΆ

 
.include "xc.inc"

.global __reset          ;The label for the first line of code.


      .bss           ;uninitialized data section
;;These start at location 0x0800 because 0-0x07FF reserved for SFRs
k:   .space 2        ;Allocating space (in bytes) to variable
j:   .space 2        ;Allocating space (in bytes) to variable.

.text                             ;Start of Code section
__reset:                          ; first instruction located at __reset label
       mov #__SP_init, w15       ;Initalize the Stack Pointer
       mov #__SPLIM_init,W0
       mov W0, SPLIM             ;Initialize the stack limit register
 ;__SP_init set by linker to be after allocated data
       rcall main              ;call main()
       reset                   ;start over

main:
       mov #13, W0
       mov WREG,j     ;j=13
 ;subroutine call
       push W0        ;push j on stack as parameter
       rcall fib
       mov WREG,k
       sub W15,#2,W15 ;clean stack of passed parameters

done:
    goto    done           ;infinite wait loop
 
 

stack frame used for n,f1 return value passed back in W0

fib:
;lnk #2 implements the push, mov, add shown below
    ;push W14          ;push FP
    ;mov  W15,W14      ;(FP=SP) new frame pointer
    ;add W15,#2,W15    ;SP=SP+2, local var space
    lnk #2
    mov [W14-8],W0    ;access n from FP
    cp W0,#0          ;n==0?
    bra Z,fib_exit    ;exit with W0=0
    cp W0,#1          ;n==1?
    bra Z,fib_exit    ;exit with W0=1
    ;set up for next call
    dec W0,W0         ;n=n-1
    push W0           ;push n-1 parameter
    rcall fib         ;fib(n-1)
    sub W15,#2,W15    ;clean n-1 parameter from stack
    mov W0,[W14]      ;save returned f1 in local
    ;set up for next call
    mov [W14-8],W0    ;access n from FP
    dec2 W0,W0        ;n=n-2
    push W0           ;save n-2 parameter
    rcall fib         ;fib(n-2)
    sub W15,#2,W15    ;clean n-2 parameter from stack
    add W0,[W14],W0   ;W0=fib(n-2)+f1
fib_exit:
;unlk implements the mov, pop shown below
    ;mov W14,W15       ;SP=FP (free local storage)
    ;pop W14           ;restore FP
    ulnk
    return            ;return f1

    .end