.nolist .include "m16def.inc" .list ;Class example ;Use a fibonacci function to illustrate parameter passing ;local storage, recursion, and macros .macro ldiw ;ldiw R, value load immediate word ;where R is one of X, Y, or Z (or any symbol ;that an H or L can be added to to make a ;register designation) ;and value is a 16 bit expression ldi @0H,high(@1) ldi @0L,low(@1) .endm .def tempr = r16 .macro dpushi ;push a constant onto the data stack push tempr ldi tempr,@0 dpush tempr pop tempr .endm .macro dpush ;push a register onto the data stack st -Y, @0 .endm ;init hardware stack - each call needs 3 bytes .equ HSTACK_SIZE = 15*3 ldi r16, high(RAMEND) out SPH, r16 ldi r16, low(RAMEND) out SPL, r16 ;init the data stack ldiw Y,RAMEND-HSTACK_SIZE+1 ;ldi YH,high(RAMEND-HSTACK_SIZE+1) ;ldi YL,low(RAMEND-HSTACK_SIZE+1) ; uint_16 f = fibo(5); .dseg f: .byte 2 ;hold the result of the fibo function .cseg dpushi 15 rcall fibo sts f,r24 sts f+1,r25 rjmp PC ;uint_16 fibo(uint_8 n); ;return the nth Fibonacci number in R25:R24 ;n is expected to be on the data stack ;fibo(0)=fibo(1)=1 ;fibo(k)=fibo(k-1)+fibo(k-2) .def returnvalueH = r25 .def returnvalueL = r24 ; a b n ;-----------------------????5-------ra-- ; Y SP #define fibo_n Y+4 #define fibo_a Y+0 #define fibo_b Y+2 fibo: sbiw Y,4 ;local storage 2 words push tempr ;if (n<=1) return 1; ldd tempr, fibo_n cpi tempr, 2 ;recursive part if n>=2 brsh fibo_difficult_part ;return 1 ldiw returnvalue, 1 ;easy part! rjmp fibo_exit fibo_difficult_part: ;uint_16 a = fibo(n-1); ldd tempr, fibo_n dec tempr dpush tempr rcall fibo std fibo_a,r24 std fibo_a+1,r25 ;uint_16 b = fibo(n-2); ldd tempr, fibo_n subi tempr, 2 dpush tempr rcall fibo std fibo_b,r24 std fibo_b+1,r25 ;return a+b; ldd returnvalueL, fibo_a ldd returnvalueH, fibo_a+1 ldd tempr, fibo_b add returnvalueL, tempr ldd tempr, fibo_b+1 adc returnvalueH, tempr fibo_exit: pop tempr adiw Y, 4+1 ret