As your programs grow in complexity, you’ll often want to reuse the same block of instructions, like printing a character or updating a score. Instead of copying and pasting code in multiple places, assembly lets you create subroutines: reusable chunks you can call whenever needed.
Subroutines keep your code clean, efficient, and easier to understand.
A subroutine is a block of code that performs a specific task.
If you’ve used BASIC before, it’s just like GOSUB
Example:
CALL PRINT
This jumps to the subroutine labelled PRINT, then resumes where it left off after a RET
Example:
RET
Every subroutine must end with RET, otherwise your program will crash or behave unpredictably
ORG 256
LD A, 200 ; Character to print
LD C, 50 ; Number of times to print
NXT: CALL PRINT ; Call subroutine to print
DEC C
INC A
JP NZ, NXT
RET
PRINT: RST 8
DEFB 158
RET
They might look similar, both jump around in your code, but how they return is key.
LD A, 0
loop:
ADD A, 1
JP loop
This repeats forever. It never returns
LD A, 42
CALL printVal
printVal:
RST 8
DEFB 158
RET
Here, CALL jumps to printVal, which prints the character, then returns back to the main program
Just like jumps, you can also do conditional calls.
Example:
CALL Z, PSPC
This calls PSPC only if the Z (zero) flag is set
Write a loop that counts down from 10 to 0 using DEC and JR NZ.
Create a subroutine that adds 1 to register A and returns. Call it from the main program using CALL.
Take your previous “print the alphabet” program and:
Write a program that calls a subroutine only if the result of a previous instruction was zero, using CALL Z,label