Introduction
The stack pointer is defined by the ABI.
- In the standard ABI and embedded ABI it is register
x2
AKAsp
. - The stack pointer is a software convention, it has no implementation in hardware or specific instructions.
- The compiler implements the stack. It is possible to program in assembler with no stack.
Initialization
The start-up code must initialize the stack before the compiler generated code is executed. The linker might define a region for the stack, or the region could be allocated at runtime. For example in SiFive’s example linker script .
.stack (NOLOAD) : ALIGN(16) {
PROVIDE(metal_segment_stack_begin = .);
. += __stack_size; /* Hart 0 */
PROVIDE( _sp = . );
PROVIDE(metal_segment_stack_end = .);
} >ram :ram
Once SP is initialized a C function can be called.
__asm__ volatile ("la sp, _sp;"
"jal zero, _start;"
: /* output: none %0 */
: /* input: none */
: /* clobbers: none */);
// This point will not be executed, _start() will be called with no return.
Other Architecture Comparison
Compared to ARM Cortex:
- NO automatic stack saving on interrupt.
- NO special instructions for multiple register push/pop.
- NO shadow stack register. (MSP/PSP)
Saving Registers in Function Calls
By default the only registers defined for saving are written to the stack on function calls.
- A function with the ‘naked’ attribute will save no registers.
- A function with the ‘interrupt’ attribute will save all registers.