Z80 assembly: Subroutines in practice

Call the same block of code twice. The stack remembers where the program must return.

CALL · RET · PUSH · POP

A subroutine is a reusable block of code. CALL saves the return address on the stack, then jumps to the subroutine. RET gets the saved address and continues after CALL. A calling convention describes which registers a subroutine may change.

CALL nn takes 17 T-states. RET takes 10. Both use the stack. PUSH and POP take 11 and 10 T-states for a register pair.

Run speed

What happened

Program listing

AddressMachine codeLabelInstructionComment

CALL is used twice. Each time it saves the address of the next instruction. RET returns there. The subroutine adds 3 to A.

Registers and stack

Flags

The stack starts at F000h and grows down. A CALL pushes a 16-bit return address. RET pops that address back into PC. The first saved return address is 0108h. The second is 010Bh.

Memory near SP

Execution trace

#AddressInstructionResultT-states

Compare with inline code

; same result without a subroutine
LD A,02h
ADD A,03h
ADD A,03h
HALT
ProgramCode sizeTime
CALL the one-instruction subroutine twice15 bytes89 T-states
Write the add instruction twice10 bytes25 T-states

For this tiny operation, inline code is shorter and faster. A longer subroutine can save code when it is reused many times. CALL and RET make the return address automatic.

This example has one level of calls and a simple stack. It does not model interrupts or nested calls from the subroutine.

Mnemonic glossary

Program mnemonics and directives
NameStands forMeaning here
LDLoadSets up SP and the starting value in A.
CALLCall subroutineSaves the return address and jumps to the routine.
ADDAddAdds 3 to A in the routine.
RETReturnRestores the saved return address to PC.
HALTHaltStops after both calls return.
ORGOriginAssembler directive. Sets the code address.