Assembly Language Fundamentals

Intermediate
Version:
1.0

Indirect Addressing

The Z80 chip also supports indirect addressing, which is different from immediate and direct modes. This is used when data is not stored directly in the instruction, but instead in the memory location pointed to by a register pair.

What Is Indirect Mode?

In this mode, instead of specifying an explicit memory address, we load from or store to the address held in a register pair, such as HL, BC, or DE.

This is especially useful when working with memory blocks, moving data, or performing pointer-style operations.

Instruction Patterns

The Z80 provides several variations of indirect addressing. Here's a breakdown of key forms:

  • LD r,(HL) – Loads register r with the contents of the memory address pointed to by HL
  • LD (HL),r – Stores the contents of register r into the memory address pointed to by HL
  • LD A,(BC) – Loads A from the address held in BC
  • LD (BC),A – Stores A at the address held in BC
  • LD A,(DE) – Loads A from the address held in DE
  • LD (DE),A – Stores A at the address held in DE
  • Example: Using HL as a Pointer

    We can use indirect mode to store multiple values to memory without writing explicit addresses.

           ORG 256
           LD BC,35900       ; Start address for storing
           LD A,65           ; ASCII code for 'A'
           LD (BC),A         ; Store 'A' at BC
           INC BC
           LD (BC),A         ; Store 'A' at next byte
           INC BC
           LD (BC),A         ; Store 'A' at next byte

    This stores three A characters into memory starting at address 35900.

    A Better Version Using a Loop

           ORG 256
           LD BC,35900       ; Pointer to memory
           LD A,65           ; ASCII for 'A'
           LD E,3            ; Number of times to store

    NXT:    LD (BC),A         ; Store A
           INC BC            ; Move pointer forward
           DEC E             ; Decrement counter
           JR NZ,NXT         ; Repeat until E = 0

    This version is shorter and clearer, using a loop to perform repeated indirect memory writes.

    Real-World Example: Writing a Message to Screen Using Indirect Mode

    To see indirect addressing in action, let’s build a program that stores a short message in memory, then reads and prints it one character at a time using a pointer.

    This simulates how a real system might walk through a string or data block stored in RAM.

    What It Demonstrates

    Print "HI" Using Indirect Addressing

           ORG 256

           LD HL,30000         ; Point to where we'll store the string
           LD A,'H'
           LD (HL),A           ; Store 'H'
           INC HL
           LD A,'I'
           LD (HL),A           ; Store 'I'
           INC HL
           LD A,0              ; Null terminator (optional for stopping later)
           LD (HL),A

           ; Reset pointer to start of string
           LD HL,30000

    READ:   LD A,(HL)           ; Load character from memory
           CP 0
           RET Z               ; End of string
           CALL PRINT
           INC HL
           JR READ

    PRINT:  RST 8
           DEFB 158            ; MCAL print character in A
           RET

    Notes

    Why This Is Realistic

    This method mimics how real operating systems, firmware, or BIOS routines process:

    Indirect addressing provides a powerful, general-purpose way to walk through data structures without hardcoding every address.

    Easy String Storage

    Surely there’s an easier way to store a string of characters? Absolutely, and in fact, assembly provides several ways to make this more convenient.

    Here’s one of the simplest:

    message:
        DEFB 'HELLO WORLD',0

    or

    message:
        DB 'HELLO WORLD',0

    This uses an assembler directive, not a Z80 CPU instruction. DB stands for Define Byte, and it tells the assembler to place the individual ASCII values for each character (including the null terminator 0) directly into memory at the current location.

    This approach allows you to define entire strings inline with your code, and the assembler handles turning them into the correct bytes.

    Summary

    Exercises

    Exercise 4.1
    Write a program that stores the values 1 to 5 in consecutive memory locations using indirect mode and a loop.

    Exercise 4.2
    Explain what the following code does and why indirect mode is used:

           LD HL,40000
           LD A,(HL)
           INC HL
           LD A,(HL)

    Previous Module
    Next Module