Hardware Reference
In-Depth Information
space to local variables at the entry point of the subroutine. If it does, then the subroutine
should have the instruction leas k,SP or its equivalent to deallocate the stack space used
by local variables before returning to the caller. The first two causes result in the incorrect
return address to be popped out from the stack. Sometimes a subroutine has several return-
ing points. Make sure to restore registers saved in the stack and deallocate local variables
before each rts instruction.
If the first two causes are not present, it is still possible that the subroutine gets stuck in
some loop. To find out if the program gets stuck in a certain loop, insert a breakpoint after the
last instruction of the suspicious loop. If the breakpoint is never reached, then you know that
the loop has some problems. Once the infinite loop is identified, you should be able to figure
out what's wrong.
To make sure that the subroutine does not get stuck after calling other subroutines, make
sure that the subroutines called by the current routine do not have the first three problems
described in this step.
4.12.2 Handling the Stack Variable Access with Care
The HCS12 does not have a frame pointer. When a subroutine with local variables needs
to call another subroutine, the programmer must pay attention to this issue. For example,
Example 4.9 calls the findSqr and div32 subroutines. It uses the following instruction sequence
to invoke findSqr:
testPR ldd pNumLo,SP ; find the square root of Num
ldx pNumHi,SP ; ''
pshd ; ''
pshx ; ''
jsr findsqr ; ''
The subroutine will not generate a correct result if the previous instruction sequence is
changed to
testPR
ldd
pNumLo,SP
pshd
ldx
pNumHi,SP
pshx
jsr findsqr
In the modified instruction sequence, the pshd instruction changes the stack offset of the
original pNumHi slot and hence the intended value is not passed to the callee.
4.12.3 General Debugging Strategy
Subroutines can be classified into two categories: intermediate and leaf subroutines.
An intermediate subroutine may call other subroutines, whereas a leaf subroutine does
not call any other subroutines. Making sure that a subroutine returns to its caller does
not guarantee that it produces correct results. You need to use the methods described in
Section 3.9.5 to debug each leaf subroutine to make sure it works correctly. After making
sure that each leaf subroutine works correctly, start to debug the intermediate subroutines.
Make sure that each intermediate subroutine does not get stuck and works correctly using
the methods discussed in Sections 4.12.1 and 3.9.5. After each intermediate subroutine has
been debugged, perform the top-level program debugging. Again, the method discussed in
Section 3.9.5 can be used.
 
Search WWH ::




Custom Search