CALL Instructions and Stack in AVR Microcontroller
CALL is a control transfer instruction that is used to call a particular subroutine. A subroutine is a block of instructions that need to be performed frequently.
In AVR, there are 4 instructions for the call subroutine as following.
- CALL (call subroutine)
- RCALL (relative call subroutine)
- ICALL (indirect call to Z)
- EICALL (extended indirect call to Z)
In this 4-byte instruction, 10 bits are used for the opcode and the other 22 bits are used for the address of the target subroutine just as in the JMP instruction. In this, 4M address space of 000000-$3FFFFF for AVR and can be used to call subroutines within the given range of address.
To make sure that the AVR knows where to come back after the execution of the subroutine, the microcontroller automatically saves the address of the instruction just below the CALL instruction on the stack. After finishing the execution of the subroutine, the RET instruction transfers control back to the caller. Hence, every subroutine has a RET instruction at the end.
Stack is the part in the RAM of CPU to store information temporarily. The CPU needs this storage because there is only a limited number of registers. The register used to access the stack is called the stack pointer (SP) register.
In I/O memory space, there are 2 registers named SPL (the low byte of SP) and SPH (the high byte of
SP). The SP is implemented by these 2 registers.
In AVRs with more than 256 bytes of memory have two 8-bit registers. On the other hand, if the memory is less than 256 bytes, SP is made up of only SPL, as an 8-bit register can only address 256 bytes of memory.
The storing of the CPU information on the stack is called the PUSH operation, and the loading of the stack contents back into the CPU is known as POP operation.
Pushing onto the stack :
The stack pointer (SP) points to the top of the stack. As we push the data onto the stack, the data is saved where the SP is pointing to and the SP is decremented by one.
To push a register onto a stack, we use PUSH instruction.
PUSH Rr; Rr can be any general-purpose register (R0 - R31)
Popping from the stack :
Popping the contents of the stack back into the register is the opposite function of pushing. When the POP instruction is executed, the SP is incremented by one and the top location of the stack is copied back to the register. This means that the stack is LIFO ( Last In First Out).
To retrieve back the data from the stack, we use POP instruction.
POP Rr; Rr can be any general-purpose register (R0 - R31)
Initializing stack pointers :
Different AVRs have different amounts of RAM. In the AVR assembler, RAMEND specifies the address of the last RAM location. So, if we want to initialize the SP so that it points to the last memory location, we can simply load RAMEND into the SP. Notice that SP is made up of 2 registers, SPH and SPL. So, we load the high byte of RAMEND into SPH and the low byte of RAMEND into SPL.
CALL instruction, RET instruction and the role of stack :
When the CALL instruction is executed, the address of the instruction below the CALL instruction is pushed onto the stack. When the execution of that subroutine is finished and RET is executed, the address of the instruction below the CALL instruction is loaded in the program counter and it is executed.