the stack and the frame pointer
The stack is the memory a function uses for its own working storage: saved registers, local variables, and the bookkeeping that lets control return to the caller. It grows downward, from higher addresses toward lower ones, and the stack pointer sp points at the lowest in-use byte.
The frame pointer fp, the register x29, marks a fixed point in the current function's slice of the stack, its frame. Because sp can move during a function, code reads and writes locals at steady offsets from fp instead, so each local keeps one stable address for the life of the call.
the prologue and epilogue
A function that calls other functions opens with a prologue and closes with an epilogue. The prologue saves the caller's frame pointer and the return address, then claims space for the new frame; the epilogue restores them and hands control back.
The pair instructions do this in one step. stp fp, lr, [sp, alloc]! stores fp and lr and moves sp down by alloc in one pre-indexed access, and ldp fp, lr, [sp], dealloc restores them and lifts sp back afterward. Between the two, mov fp, sp anchors the frame.
// the frame skeleton: prologue, one local by fp offset, epiloguedefine(fp, x29)define(lr, x30)define(n_r, w9)n_s = 16alloc = -(16 + 16) & -16dealloc = -alloc .datafmt: .string "n = %d\n" .text .balign 4 .global mainmain: stp fp, lr, [sp, alloc]! // save fp+lr and open the frame mov fp, sp mov w0, 5 str w0, [fp, n_s] // store a local at fp+16 ldr n_r, [fp, n_s] // read it back by its offset ldr x0, =fmt mov w1, n_r bl printf mov w0, 0 ldp fp, lr, [sp], dealloc // restore fp+lr and close the frame retOpen in playgroundwarning
Two rules keep a frame correct. First, sp must stay 16-byte aligned at every point where another function might run, which is why the frame size is rounded with & -16. Second, a function that calls anything must save fp and lr on entry and restore them before it returns: lr holds the address to return to, and a call overwrites it, so losing it strands the function with no way back.
locals in the frame
Local variables live at fixed offsets above fp. Storing one is str w0, [fp, 16]; reading it back is ldr w1, [fp, 16]. The offsets are yours to choose, as long as they stay inside the space the prologue reserved.
The reserved size comes from the alignment formula alloc = -(16 + locals) & -16, where locals is the number of bytes the function needs. The & -16 rounds the frame up to a multiple of sixteen so the stack keeps its alignment, and the leading sixteen bytes hold the saved fp and lr pair. The two editors below allocate frames, fill locals with fixed values, and read them back by offset.