Documente Academic
Documente Profesional
Documente Cultură
Han-Way Huang
The Stack
low bottom
address
Figure 4.2 The PIC18 Software Stack
Stack Macros
- Push and pop operations are often performed during a subroutine call.
- The user often needs to allocate and deallocate stack space during a subroutine call.
- Allocation and deallocation of stack space are performed during subroutine calls.
push_dat
macro dat ; this macro push the value dat onto the stack
movlw dat
pushr WREG
endm
pushrPRODL
popr PRODL
push_dat 0x20
alloc_stk 10
dealloc_stk 10
Subroutines
- A sequence of instructions that can be called from many different places in a
program.
- Parameters can be passed to the subroutine so that it can perform operations on
different variables.
- Allows the user to use divide-and-conquer strategy to solve complicated
problems.
- Using subroutines can in some cases reduce the code size significantly.
local variables
saved registers
FSR2 (frame pointer)
previous frame pointer
incoming parameters
FSR1
loop_cnt
in_order
sum
Increasing addresses
5
4 k
3
2 j
1
0 i FSR2
previous FSR2 -2
-3
n
m
Example 4.9 Write a subroutine to find the maximum element of an array of 8-bit
elements in program memory. Pass the array count and starting address in the
software stack.
Solution:
The caller of this subroutine will
1. Push the low part of the array starting address onto the stack.
2. Push the high part of the array starting address onto the stack.
3. Push the upper part of the array starting address onto the stack.
4. Push the array count onto the stack.
#include <p18F8720.inc>
radix dec
acnt equ 32 ; array count
lp_cnt equ 3 ; stack frame offset for lp_cnt
ar_max equ 4 ; stack frame offset for array max
ar_cnt equ -3 ; stack frame offset for array count
arr_xup equ -4 ; stack frame offset for array base
arr_xhi equ -5 ; "
arr_xlo equ -6 ; "
array_max set 0x00 ; register to hold array max
org 0x00 ; reset vector
goto start
org 0x08
retfie
org 0x18
retfie
start lfsr FSR1,0xE00 ; set up software stack pointer
movlw low arr_x ; pass array base in the stack
pushr WREG ; "
movlw high arr_x ; "
pushr WREG ; "
movlw upper arr_x ; "
decf PRODL,F,A
movlw lp_cnt
movff PRODL,PLUSW2 ; initialize lp_cnt to arcnt-1
movlw arr_xlo ; place array pointer in TBLPTR
movff PLUSW2,TBLPTRL ; "
movlw arr_xhi ; "
movff PLUSW2,TBLPTRH ; "
movlw arr_xup ; "
movff PLUSW2,TBLPTRU ; "
tblrd*+ ; assign arr_x[0] as the initial array max
movlw ar_max ; "
movff TABLAT,PLUSW2 ; "
cmp_lp movlw lp_cnt
tstfsz PLUSW2
goto next
goto done
next movlw lp_cnt
decf PLUSW2,F ; decrement the loop index
tblrd*+ ; read in the next array element
movlw ar_max
movf PLUSW2,W,A
cpfsgt TABLAT
movlw ar_max
movff TABLAT,PLUSW2 ; update the current array max
goto cmp_lp
done movlw ar_max
movff PLUSW2,PRODL
dealloc_stk 2 ; deallocate local variables
popr TBLPTRU
popr TBLPTRH
popr TBLPTRL
popr FSR2H
popr FSR2L
return FAST
; define an array of 32 8-bit elements.
arr_x db 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
db 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
end