← r0mheat z80 lessons: all projects

Z80 assembly: The stack

Save register values, call a subroutine, and return to the instruction after CALL.

PUSH · POP · CALL · RET

The stack is a last-in, first-out area in memory. SP is the Stack Pointer. PUSH moves SP down and stores two bytes. POP reads two bytes and moves SP up. CALL saves the return address. RET restores it to PC.

PUSH takes 11 T-states. POP takes 10. CALL takes 17. RET takes 10. Words are stored low byte first at the address in SP.

Run speed

What happened

Program listing

AddressMachine codeLabelInstructionComment

ORG 0100h places this program at 0100h. It stores BC on the stack, copies it into DE, then calls a one-instruction subroutine. SP starts at F000h; each PUSH or CALL decrements SP before writing, so the stack grows toward lower addresses.

Registers and stack memory

Flags

CALL puts the address after its 3-byte instruction on the stack. RET reads that address and continues there. PUSH and POP of a register pair do not change flags. Z80 words are little-endian: the low byte is at the lower address. For PUSH BC with BC=1234h, memory EFFEh=34h and EFFFh=12h. CALL at 0108h saves return address 010Bh in the same order: EFFEh=0Bh, EFFFh=01h. RET reads that word back into PC.

Bytes near SP

Follow SP through the example

OperationSP afterwardMemory effectWhat happens next
Before PUSHF000h—BC holds 1234h.
PUSH BCEFFEhEFFEh = 34h; EFFFh = 12hSP points to the low byte.
POP DEF000hReads 34h, then 12hDE becomes 1234h.
CALL routineEFFEhEFFEh = 0Bh; EFFFh = 01hReturn address 010Bh is saved; PC jumps to 010Ch.
RETF000hReads 0Bh, then 01hPC returns to 010Bh, the HALT instruction.

The byte values appear in little-endian order. SP points at the first byte to be popped; each 16-bit push or pop changes SP by two.

Execution trace

#AddressInstructionResultT-states

Why use the stack?

ActionStack formManual alternative
Save BC temporarilyPUSH BC · 11 TCopy B and C elsewhere; requires spare registers.
Restore BCPOP BC · 10 TCopy both saved bytes back in the correct order.
Run a subroutineCALL · RETManually save and restore the return address.

The stack makes nested subroutine calls possible because each CALL saves its own return address.

This lesson uses ordinary memory for the stack. It does not model interrupts, stack protection, or hardware memory mapping.

Mnemonic glossary

Program mnemonics and directives
NameStands forMeaning here
LDLoadInitializes SP and BC.
PUSHPush onto stackSaves BC in two memory bytes.
POPPop from stackRestores those bytes into DE.
CALLCall subroutineSaves the return address and jumps.
RETReturnLoads the saved address into PC.
ORGOriginAssembler directive. Sets the code address.
HALTHaltStops after the subroutine returns.