A register which holds the address of the "top of stack" element (this is for stacks which grow upwards; note that if your stack grows downwards, you'll be talking about the bottom of stack or risk getting very confused). Also, just to confuse you, sometimes the stack pointer points at the actual top element, and sometimes one place beyond it. For writing ISO C, you usually want the latter option, or you cannot legally represent an empty stack. So we'll use it, too.
Stack pointers exist in hardware in almost any CPU (and some have more than one). They also exist in software, whenever a program implements a stack. The workings, however, are the same.
Assuming the stack pointer is in sp (for software implementations in C, assume sp is compatible with the declaration item *sp, for an appropriate type item), we can define PUSH and POP.
- PUSH data
- is just *sp++ = data
- POP var
- is var = *--sp.
Software implementations may add some protections (against PUSHing onto a full stack,
aka stack overflow, or POPping an empty one, aka
stack underflow), but hardware implementations typically don't.