Z80 assembly: Strings, fast fill and copy

A string is a sequence of character bytes. Fill a memory range, then copy a string with LDIR.

DB · DJNZ · LDIR

A string is stored as one byte per character. This example uses ASCII bytes for “Z80!”. A fill loop writes the same value to several addresses. LDIR copies a block forward and updates HL, DE and BC after each byte.

The fill loop takes 26 T-states for each continuing byte and 21 for the last. LDIR takes 21 T-states while repeating and 16 on its last byte.

Run speed

What happened

Program listing

AddressMachine codeLabelInstructionComment

The program fills 011Bh–011Eh with 2Ah. Then it copies the four bytes at 0117h–011Ah to 011Fh–0122h.

Registers and memory

Flags

ASCII assigns a number to each character. Z is 5Ah, 8 is 38h, 0 is 30h, and ! is 21h. The bytes are not stored as special string objects.

Source, fill and copy areas

Execution trace

#AddressInstructionResultT-states

Block instruction or manual loop?

TaskCodeContinuing byteLast byte
LDIR copy2 bytes21 T16 T
LD A,(HL) + LD (DE),A + pointer updates + branch7 bytes44 T39 T
Fill loop: LD (HL),A + INC HL + DJNZ4 bytes26 T21 T

LDIR copies from a source range. It cannot repeat one source byte to fill a range, because HL moves after each copy. Use a fill loop for repeated values.

The string has a fixed length of four bytes and no zero terminator. Real programs can use a terminator or a separate length value.

Mnemonic glossary

Program mnemonics and directives
NameStands forMeaning here
LDLoadSets up values and writes fill bytes.
INCIncrementMoves HL to the next memory byte.
DJNZDecrement B and Jump if Not ZeroRepeats the fill loop four times.
LDIRLoad, Increment, RepeatCopies the string bytes forward.
DBDefine ByteAssembler directive. Stores the string bytes.
DSDefine SpaceAssembler directive. Reserves fill and copy ranges.
HALTHaltStops after the copy.