Strings — sequences of characters stored in memory — are the foundation of almost every program that needs to display messages, interact with users, or manage text. In Z80 assembly, working with strings requires us to understand how data is stored, how to loop through it, and how to know when to stop reading.
In this lesson, we’ll keep things simple and focused. We won’t deal with tables or pointers yet — those come later. Here, the goal is to make sure you’re completely comfortable with how strings are represented in memory and how to process them one byte at a time.
At the lowest level, a string is just a sequence of character bytes stored in consecutive memory locations. Each character is represented by its ASCII value. Most Z80 programs store strings with a null terminator — a 0 byte that marks the end of the string.
For example:
welcome_msg:
DEFB "Hello, world!", 0
This places the following bytes in memory:
48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00
H e l l o , w o r l d ! (0 terminator)
The 0 at the end tells our code where to stop printing.
To display a string, we load its memory address into HL and use a loop to print each character until we find the 0.
Here’s a simple printing routine:
print_string:
LD A, (HL) ; Load the current character into A
CP 0 ; Compare with 0 (null terminator)
RET Z ; If 0, we’re done
RST 8
DEFB 158 ; Print the character
INC HL ; Move to the next byte
JR print_string ; Repeat
How it works:
LD A, (HL) gets the character from memory.CP 0 checks if it’s the terminator.RET).HL, and loop back.You can define as many strings as you like — each with its own label — and print them by simply loading their address into HL before calling print_string.
message1:
DEFB "System ready.", 0
message2:
DEFB "Press any key to continue...", 0
start:
LD HL, message1
CALL print_string
LD HL, message2
CALL print_string
This is still simple: we’re manually choosing which string to print by loading the address directly. No pointer calculations, no indexing — just direct memory access.
msg1, msg2, msg3) and write a program that prints them one after another.A.0 to mark its end.HL and calling the same print routine.