Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Arbitrary Code Execution Discussion

How to do loops in GBZ80 assembly? - Page 1

How to do loops in GBZ80 assembly?

Posted by: joshuarpl
Date: 2019-01-02 14:51:54
Hi, Recently I've been wondering how I do loops in assembly, because I kinda wanna do ZZAZZ glitch trainer arbitrary code execution, but if the code ends because of ret, It might crash the game!
Could you tell me how to do looping in GBZ80 assembly please?

Also, Happy New Year!

Re: How to do loops in GBZ80 assembly?

Posted by: Sherkel
Date: 2019-01-02 15:08:21
ld a,amount of times
(Instructions)
dec a
jr nz, (pointer to above instructions)
?

I'm obviously not the best one to ask, but I know you can do something along those lines.

Re: How to do loops in GBZ80 assembly?

Posted by: ISSOtm
Date: 2019-01-02 19:19:33
It's generally a jump back to the loop point. Whatever the condition is, really.

Re: How to do loops in GBZ80 assembly?

Posted by: joshuarpl
Date: 2019-01-03 13:29:33

ld a,amount of times
(Instructions)
dec a
jr nz, (pointer to above instructions)
?

I'm obviously not the best one to ask, but I know you can do something along those lines.


A loop address doesn't really seem to help me all that much, is there a way to name a loop like in 6502?
in 6502 it would be
loop:
(whatever the loop does)
JMP loop

But what would that be in GBZ80 assembly?

Re: How to do loops in GBZ80 assembly?

Posted by: Sherkel
Date: 2019-01-03 16:25:54
…No? I mean, you can give a piece of code whatever name you want, but it won't be part of the executed instructions themselves. I don't know what you're referring to about 6502. Maybe I'm missing something. Anyway, as Isso said, just keep jumping back to a given point.

Re: How to do loops in GBZ80 assembly?

Posted by: Parzival
Date: 2019-01-03 19:15:25


ld a,amount of times
(Instructions)
dec a
jr nz, (pointer to above instructions)
?

I'm obviously not the best one to ask, but I know you can do something along those lines.


A loop address doesn't really seem to help me all that much, is there a way to name a loop like in 6502?
in 6502 it would be
loop:
(whatever the loop does)
JMP loop

But what would that be in GBZ80 assembly?

If you want an infinite loop, like the example code implies, you'd have to know where the first opcode is, as (using the name in your example) "loop" isn't an actual place, it's a compiler thing to make loops easier since you wouldn't necessarily know where the code IS until after building.

Say your code starts at A000 (this is an EXAMPLE, it probably won't), you'd do something like this for an infinite loop:
<some code or w/e>
jp A000

or, depending on the code length, you could save one byte of space and a cycle if you use a "jr A000" instead, but the code can't be more than (IIRC) 120 bytes for that.

If you want it to jump somewhere else when some condition is met, you'd do something like this at A000 (this example is for jumping away after a certain number of loops):

ld a,<loopnumber>
<code>
dec a
jr nz,A002
jp <somewhere>

You have to jump back to AFTER the first ld a statement or it'll never finish as you reset the a register every loop.

These are just examples, but feel free to use them, I guess.

Re: How to do loops in GBZ80 assembly?

Posted by: ISSOtm
Date: 2019-01-03 19:33:02
You can use labels in GBz80:

FillMemory: ; Global label
    inc c
    inc b
    jr .skip
.loop ; Local label
    ld [hli], a
.skip
    dec c
    jr nz, .loop
    dec b
    jr nz, .loop
    ret

Note that `jr` is different in the way the target address is specified; `jp` just spells it out, `jr` uses a signed offset instead.

Re: How to do loops in GBZ80 assembly?

Posted by: Parzival
Date: 2019-01-04 01:37:18

You can use labels in GBz80:

FillMemory: ; Global label
    inc c
    inc b
    jr .skip
.loop ; Local label
    ld [hli], a
.skip
    dec c
    jr nz, .loop
    dec b
    jr nz, .loop
    ret

Note that `jr` is different in the way the target address is specified; `jp` just spells it out, `jr` uses a signed offset instead.
That only works when compiling, there's no way to specify those with an opcode. That's what we're saying.

Re: How to do loops in GBZ80 assembly?

Posted by: ISSOtm
Date: 2019-01-04 06:33:41
gbz80toitems supports labels, and if you're going for complex code, you should definitely use that.
Unless you want hex output, in which case I don't think there's any better solution that using RGBDS directly and looking at the output binary.

Re: How to do loops in GBZ80 assembly?

Posted by: joshuarpl
Date: 2019-01-08 10:36:34



ld a,amount of times
(Instructions)
dec a
jr nz, (pointer to above instructions)
?

I'm obviously not the best one to ask, but I know you can do something along those lines.


A loop address doesn't really seem to help me all that much, is there a way to name a loop like in 6502?
in 6502 it would be
loop:
(whatever the loop does)
JMP loop

But what would that be in GBZ80 assembly?

If you want an infinite loop, like the example code implies, you'd have to know where the first opcode is, as (using the name in your example) "loop" isn't an actual place, it's a compiler thing to make loops easier since you wouldn't necessarily know where the code IS until after building.

Say your code starts at A000 (this is an EXAMPLE, it probably won't), you'd do something like this for an infinite loop:
<some code or w/e>
jp A000

or, depending on the code length, you could save one byte of space and a cycle if you use a "jr A000" instead, but the code can't be more than (IIRC) 120 bytes for that.

If you want it to jump somewhere else when some condition is met, you'd do something like this at A000 (this example is for jumping away after a certain number of loops):

ld a,<loopnumber>
<code>
dec a
jr nz,A002
jp <somewhere>

You have to jump back to AFTER the first ld a statement or it'll never finish as you reset the a register every loop.

These are just examples, but feel free to use them, I guess.


Well, I figured it out… kindof! I use the jp instruction, and jump to whatever the instruction I wanna jump to is at!

Re: How to do loops in GBZ80 assembly?

Posted by: Sherkel
Date: 2019-01-08 11:41:30
That's what we were all saying, but it's good to hear you figured it out.