Skip to content

Instantly share code, notes, and snippets.

@neuro-sys
Last active November 8, 2023 11:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neuro-sys/1307c53cb1647cb5056c to your computer and use it in GitHub Desktop.
Save neuro-sys/1307c53cb1647cb5056c to your computer and use it in GitHub Desktop.
How to Write a For-Loop in Z80 Assembly

Write a For-Loop in Z80 Assembly

Note, this is intended for a beginner (as I was at the time when I wrote this) who thinks in terms of high level languages.

Firstly, it's best to type down what exactly we'd like to write in a higher level language:

int i;

for ( i = 0 ; i < 10 ; i++ ) {
    /* do something */
}

As per C-like languages, iteration statement is defined as follows:

for ( <statement> ; <expression> ; <expression> )
    <statement...>

For convenience I give a name to expressions in the for statement as such:

for ( loop_init ; loop_cond ; loop_next )
    loop_body
loop_end

In for-loop, the order of execution in expressions as follows:

for ( [1] ; [2] ; [4] )
    [3]
[5]

In assembly we'll first place our labels in their order of execution acording to for-loop:

.loop_init   // [1]

.loop_cond   // [2]

.loop_body   // [3]

.loop_next   // [4]

.loop_end   // [5]

Using the above template, we can now write a for-loop as follows (for convenience I am using 8-bit register b for the index variable):

.loop_init   
    ld b, #0                ;; i = 0
.loop_cond   
    ld a, 10                ;; i != 10
    cp b
    jp z, loop_exit
.loop_body   
                            ;; do something
.loop_next   
    inc b                   ;; i++
    jp loop_cond
.loop_end   

For clarity is important, there is no harm in keeping unused labels in there. But if you like, they can be omitted for brevity:

    ld b, #0                ;; i = 0
.loop_cond   
    ld a, 10                ;; i != 10
    cp b
    jp z, loop_exit
                            ;; do something
    inc b                   ;; i++
    jp loop_cond
.loop_exit
@rgngl
Copy link

rgngl commented Mar 17, 2015

👍

@skeletozaure
Copy link

Thanks a lot

@oxy1914
Copy link

oxy1914 commented Nov 8, 2023

Why not to use one DJNZ command instead of two? i.e.

.loop_init
  LD b, 10
  JPR .loop_cond
.loop_body
  ;...
.loop_cond
  DJNZ .loop_body
.loop_exit

@neuro-sys
Copy link
Author

@oxy1914 Yes, that would be the right way. I think at the time I just wanted to demonstrate intuitively how it maps to a for loop. In my own z80 code I use djnz or whatever appropriate. I should probably give context, or just delete this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment