(A bit off-topic, but i thought i'd share in anycase)
In this instance it's not very efficient to use the index registers, but if you've got a lot of data per pointer, for example a list of enemies with an x and y location, x and y velocity, id, animation frame, action id, etc. putting the address into ix can be really handy, particularly since you rarely touch them so you don't generally have to worry about it getting changed. I often use ix for handling bullets and enemies. Here's something from one of my games:
Code: ;enemy constants
MAX_ENEMIES = 25
ENEMY_SIZE = 9
EID = 0
EX = 1
EY = 3
EPAT = 5
EFRAME = 6
EHP = 7
ESHOOT = 8
;bullet constants
MAX_BULLETS = 50
BULLET_SIZE = 7
BID = 0
BX = 1
BY = 3
BFRAME = 5
BDMG = 6
If i'm messing with enemies, i do something like ld ix,enemy_array. If i want to read the x or y values, i can just do ld a,(ix+EX) or ld a,(ix+EY). If hit the enemy, i can do dec (ix+EHP). If the enemy is dead, i can ld (ix+EID),$FF. The best part is that i don't have to keep track how far i am in hl and when i've reached the end of the necessary stuff for that enemy i can just add ix,ENEMY_SIZE,
Back on topic, in some assembly languages (like ARM) you can have the register automatically increase when you read from it. The z80 doesn't, so if you want to read the next byte, you have to increase every time.
If you wanted to display the list of scores, for example, you would have something like this:
Code: ld hl,Scores
ld b,8
score_loop:
ld e,(hl)
inc hl
ld d,(hl)
inc hl
call disp_score
djnz score_loop
...though you'd probably need to put hl and bc on the stack since disp_score will most likely change their values.