RosettaCodeData/Task/Array-length/Z80-Assembly/array-length.z80

46 lines
1.3 KiB
Z80 Assembly

org &8000
ld hl,TestArray
call GetArrayLength_WordData_NullTerminated
call Monitor ;show registers to screen, code omitted to keep this example short
ReturnToBasic:
RET
GetArrayLength_WordData_NullTerminated:
push hl ;we'll need this later
loop_GetArrayLength_WordData_NullTerminated
ld a,(hl) ;get the low byte
ld e,a ;stash it in E
inc hl ;next byte
ld a,(hl) ;get the high byte
dec hl ;go back to low byte, otherwise our length will be off.
or a ;compare to zero. This is a shorter and faster way to compare A to zero than "CP 0"
jr nz,keepGoing
cp e ;compare to E
jr z,Terminated_GetArrayLength ;both bytes were zero.
KeepGoing:
inc hl
inc hl ;next word
jp loop_GetArrayLength_WordData_NullTerminated ;back to start
Terminated_GetArrayLength:
pop de ;original array address is in DE
;or a ;normally it's best to clear the carry, but in this situation execution only arrives here after a compare that
;resulted in an equality to zero, which means the carry is guaranteed to be cleared.
sbc hl,de ;there is no sub hl,de; only sbc
srl h
rr l ;divide HL by 2, since each element is 2 bytes.
ret ;returns length in hl
TestArray:
word Apple,Orange
byte 0,0
Apple:
byte "Apple",0
Orange:
byte "Orange",0