User`s manual

192 digi.com Using Assembly Language
11.8 Common Problems
If you have problems with your assembly code, consider the possibility of any of the following situations:
Unbalanced stack.
Ensure the stack is “balanced” when a routine returns. In other words, the SP must be same on
exit as it was on entry. From the callers point of view, the SP register must be identical before
and after the call instruction.
Using the @SP approach after pushing temporary information on the stack.
The @SP approach for inline assembly code assumes that SP points to the low boundary of the
stack frame. This might not be the case if the routine pushes temporary information onto the
stack. The space taken by temporary information on the stack must be compensated for.
The following code illustrates the concept.
; SP still points to the low boundary of the call frame
push hl ; save HL
; SP now two bytes below the stack frame!
...
ld hl,@SP+x+2 ; Add 2 to compensate for altered SP
add hl,sp ; compute as normal
ld a,(hl) ; get the content
...
pop hl ; restore HL
; SP again points to the low boundary of the call frame
Registers not preserved.
In Dynamic C, the caller is responsible for saving and restoring all registers. An assembly rou-
tine that calls a C function must assume that all registers will be changed.
Unpreserved registers in interrupt routines cause unpredictable and unrepeatable problems. In
contrast to normal functions, interrupt functions are responsible for saving and restoring all
registers themselves.
Relocatable code.
Jump relative (JR) instructions allow easier code relocation because the jump is relative to the
current program counter. For example, RAM functions are usually written in assembly and are
relocated to RAM from flash. A jump (JP) instruction would not work in this case because the
jump would be to a flash location and not the intended RAM location. Using JR instead of JP
will jump to the intended RAM location.