8.5.4 Stack and Stack Pointer

The stack is used for storing return addresses after interrupts and subroutine calls. Also, it can be used for storing temporary data. The Stack Pointer (SP) always points to the top of the stack. The SP is defined by the Stack Pointer bits in the Stack Pointer register (CPU.SP). The CPU.SP is implemented as two 8-bit registers that are accessible in the I/O memory space.

Data are pushed and popped from the stack using the PUSH and POP instructions. The stack grows from higher to lower memory locations. This means that pushing data onto the stack decreases the SP, and popping data off the stack increases the SP. The SP is automatically set to the highest address of the internal SRAM after being reset. If the stack is changed, it must be set to point above the SRAM start address (see the SRAM Data Memory section in the Memories chapter for the SRAM start address), and it must be defined before any subroutine calls are executed and before interrupts are enabled. See the table below for SP details.

Table 8-1. Stack Pointer Instructions
Instruction Stack Pointer Description
PUSH Decremented by 1 Data are pushed onto the stack

CALL
ICALL
RCALL

Decremented by 2 A return address is pushed onto the stack with a subroutine call or interrupt
POP Incremented by 1 Data are popped from the stack

RET

RETI

Incremented by 2 A return address is popped from the stack with a return from subroutine or return from interrupt

During interrupts or subroutine calls, the return address is automatically pushed on the stack as a word pointer, and the SP is decremented by two. The return address consists of two bytes and the Least Significant Byte (LSB) is pushed on the stack first (at the higher address). As an example, a byte pointer return address of 0x0006 is saved on the stack as 0x0003 (shifted one bit to the right), pointing to the fourth 16-bit instruction word in the program memory. The return address is popped off the stack with RETI (when returning from interrupts) and RET (when returning from subroutine calls), and the SP is incremented by two.

The SP is decremented by ‘1’ when data are pushed on the stack with the PUSH instruction, and incremented by ‘1’ when data are popped off the stack using the POP instruction.

To prevent corruption when updating the SP from software, a write to SPL will automatically disable interrupts for up to four instructions or until the next I/O memory write, whichever comes first.