The Need for a Detailed Compare
The standard `memcmp′ routine (Part 89) tells you only if two blocks are the same or different. For debugging purposes, you often need to know where the corruption or difference first occurred.
Goal: Compare two memory blocks, and if they differ, return the address of the first byte that does not match.
The Comparison Strategy
We will modify the simple comparison loop to preserve the address and exit immediately upon the first failure.
Key Registers Setup:
Register Pair | Purpose |
---|---|
HL | Source Address 1 (The reference block). |
DE | Source Address 2 (The block being checked). |
BC | Counter (The total number of bytes to check). |
The Z80 Compare Routine
The routine performs a byte-by-byte comparison and uses the `RET′ instruction to exit quickly.
The Z80 Routine:
CMP_BLOCK_WITH_DIFF:
; Assume HL = Block 1, DE = Block 2, BC = length
CMP_LOOP:
LD A, (HL) ; A ← Byte from Block 1
CP (DE) ; Compare A with byte from Block 2
JP NZ, DIFFERENCE_FOUND ; Jump if Not Zero (mismatch!)
INC HL ; Advance Block 1 pointer
INC DE ; Advance Block 2 pointer
; 16-bit decrement of counter (BC)
DEC BC
LD A, B ; Check if BC is zero
OR C
JP NZ, CMP_LOOP ; Loop if BC is Not Zero
; --- Blocks are fully identical ---
XOR A ; Set Z flag (A=0) to signal identity
RET ; Exit (HL points one byte past the end)
DIFFERENCE_FOUND:
; --- Mismatch found at (HL) and (DE) ---
; Result: HL still points to the address of the mismatch.
RET ; Exit with Z flag NOT set
Interpreting the Results
After the routine finishes, the status of the Zero Flag (Z) and the HL register provide the necessary information:
Condition | Zero Flag (Z) | HL Register Value |
---|---|---|
Identical Blocks | 1 (Set) | Address immediately after the end of the block. |
Mismatch Found | 0 (Cleared) | Address of the first differing byte in Block 1. |
Debugging Usage: This routine is ideal for loading a large resource file (like a game level) and comparing it against a verified copy to instantly locate the point of file corruption.