JP label | Causes execution to jump to label. |
JR label | Causes execution to jump to label. |
Example:
LD A, 25 INC A JR SkipOver SUB 12 ; These two statements are never executed. ADD A, B SkipOver: ; JR branches to here. JR Exit ; Results in an error because the exit label is too far away. ; Pretend a whole lotta stuff is here. ; Exit: RETJR and JP, when used in this way, are unconditional. That is, execution will always jump to the specified label. This is nice, but not always useful. What we can do is use conditionals so that the jump is taken only when certain conditions are met. If not, the instruction will just be ignored.
JP condition, label
condition is any one of the conditions listed below.
Z | If the zero flag is set. | NZ | If the zero flag is reset. |
---|---|---|---|
C | If the carry flag is set. | NC | If the carry flag is reset. |
PE | If the parity/overflow flag is set. | PO | If the parity/overflow flag is reset. |
M | If the sign flag is set. | P | If the sign flag is reset. |
One of the best ways to set off a conditional jump is to use the CP instruction. CP is identical to the SUB instruction except that the accumulator is left intact. Its only job is to compare how the accumulator relates to another value.
CP { imm8 | reg8 | (HL) } | Subtracts the operand from the accumulator, but does not actually affect the accumulator. | ||||||||
|
Comparison | Unsigned | Signed |
---|---|---|
A == num | Z flag is set | Z flag is set |
A != num | Z flag is reset | Z flag is reset |
A < num | C flag is set | S and P/V are different |
A >= num | C flag is reset | S and P/V are the same |
CP 20 JR Z, label1 ; If the accumulator is 20, then will jump. CP 15 ; If it isn't, then... JR Z, label2 ; If the accumulator is 15, then will jump. CP 10 ; If it isn't, then... JR NC, label3 ; If the accumulator is 10 or more, then will jump.I'm going to guess, that since all you have to do is check the carry flag, and are able to use JR, you'll be keeping all your comparisons unsigned. Although you may need to a signed comparison now and then. In that case, you'll need to know how to chain conditions.
E.g. this C code
if( (a >= 7) && (a != 8) ) goto success; else goto fail;could be translated into assembly as
CP 7 JR C, fail CP 8 JR Z, fail success: ;This code executed if condition passes. fail: ;This code executed if condition fails.
E.g.
if( (a >= 7) || (a != 8) ) goto success; else goto fail;
CP 7 JR NC, success CP 8 JR NZ, success fail: ;This code executed if condition fails. success: ;This code executed if condition passes.
E.g.
if( (a >= 7 && a != 8) || a == 1 ) goto success; else goto fail;Let's see? Looking at the expression, because it's OR, if A equals 1 then the entire expression will be true, so:
CP 1 JR Z, successIn the event there was no jump, then we can still jump to success if A is both greater than or equal to seven while not being equal to eight (again, because it's OR). So you just put in the conjunction construction:
CP 7 JR C, fail CP 8 JR Z, fail success: . . . fail: . . .
LD IX, AppBackupScreen ; Get array base LD DE, sizeof ; Use this to update IX LD A, (IX + x) ADD A, (IX + dx) LD (IX + x), A ADD IX, DE LD A, (IX + x) ADD A, (IX + dx) LD (IX + x), A ADD IX, DE LD A, (IX + x) ADD A, (IX + dx) LD (IX + x), A ADD IX, DE LD A, (IX + x) ADD A, (IX + dx) LD (IX + x), AYou ought to see that there is a set of three instructions (four if you append an extra ADD) that are repeated over and over. In cases like these it is simply not practical to write out the code again and again for as many times as we require, and furthermore the number of repetitions necessary might change as the program runs. To relieve burdens such as this, you can and should create a loop.
A loop is nothing more than a collection of instructions that are to be executed multiple times. All loops consist of three components: an initialization, a termination test, and a loop body. The initialization is simply the setup before the loop starts. The termination test is used by the loop to see if it should stop or repeat. The loop body is the statements not dedicated to control of the loop that are executed. The permutations of these three components dramatically change the way a loop operates.
while (expression) { statements }There is one important aspect of the while loop: the test for termination appears at the start of the loop. As a direct consequence, the loop body may never even be executed.
Consider the following implementation of a while loop:
int x = 0; while (x < 100) x++;x = 0 is the initialization. x < 100 is the termination condition i.e. the loop will not end as long as x is less than 100. x is termed a loop control variable, because it controls whether or not the loop will terminate. x++ is the body and is the code that executes on each pass through the loop.
LD A, 0 ; Initialization While: CP 100 ; Loop termination test JR C, EndWhile INC A ; Loop body JR While EndWhile:
int x = 0; do { x++; } while (x < 100); LD A, 0 Do: INC A CP 100 JR NZ, Do
The do-style loop, you'll notice, has one less jump instruction in it than its while counterpart. Therefore the do...while loop runs faster, so always, always use do...while loops! If you need to check the inital value of the test variable, do it just before the loop begins.
DJNZ label | Subtracts 1 from register B, and if it isn't zero, jumps to label. |
LD B, 100 loop: DEC A DJNZ loopDJNZ is functionally equivalent to the following insructions (minus the modification to the flags), so if circumstances dictate that you can't use B, you know how to fabricate a replacement:
DEC B JR NZ, labelThe choice of JR was intentional, because both instructions are subject to the same range limitations. Be aware, too, that because DJNZ decrements B before it checks if it is zero, an initial value of zero for B will result in an overflow and 256 iterations. Therefore, you may want to check the value of B before entering the loop if this would be a concern.
CALL label | Causes execution to jump to label, returning when a RET instruction is executed. |
Procedures are too intricate to do them justice in just a couple paragraphs. In fact a whole day has been delegated to explain them further.