Flags and Conditions

z80 » Beginner

Where would we be without If/Then statements? They're called conditions in asm. There is no If command in asm. Don't worry though. We have what are called 'flags'. Remember when I was telling you about the register pairs? Do you remember that a didn't have a partner? It does, and it's f. Af is the registered pair. The z80 has six flags on it total, which are represented in the f register as being either set (1) or reset (0). Remember that the f register contains the flags as bits. The most commonly used flags are the 'zero flag' and the 'carry flag', we will learn about the others later on.

Zero Flag

The zero flag is used to show us whether the value of the indicated operation is zero: a subtraction resulted in a zero, a decriment ended up being zero, or there was zero difference between the two values compared.

For instance, when you have $01 stored in b and perform dec b, the zero flag will be set because b has reached zero; but if b contains $02 and you perform dec b, the zero flag will be reset because it will be at $01 still.

Another example is when you have $09 stored in a and you do a cp $09. The processor will subtract $09 from a and set the zero flag because the answer is zero.

Carry Flag

The carry flag tells us the resultant value was too big to be stored in the register.

When you perform a command that results in a 9 bit answer that can not be stored in the 8 bit register, the 9th bit is stored in the carry flag's spot on the f register. The carry flag is usually used in shift and rotate instructions which we will learn about later.

These flags are either set or reset by either a comparison or a testing instructions. The flags will also remain set or reset until a new comparative instruction is executed, this means that you could have a comparative command, some code, and then the conditional branch (jump).

	cp arg1

Here's a chart that compares the flag states to test operands. The argument is subtracted from a without modifying a, i.e. a - arg1. If arg1 is greater than a then a carryover event happens and the carry flag is set. If arg1 is less than a, then no event occurred so the carry flag is reset.

Assembler Flag Change
arg1 > a Carry set
arg1 <= a Carry reset
arg1 == a Zero set
arg1 != a Zero reset

The following examples might help:

ld a,255
inc a
ZF CF The answer is not zero but it is a nine bit answer. A now contains %00000000.
ld a,1
dec a
ZF CF We just decreased a by one which made it zero.
ld a,$10
Nothing happened with the flags because there was no test instruction.
ld a,1
sub a
ZF NC We 'subtracted' a from a. A is now zero.
ld hl, $def4
add hl, hl
ZF CF We went way over the limit (65535) for a word, but it's still not zero.
ld a,$40
cp $41
ZF CF We subtracted so much from a that it went under zero to -1 which in binary would be like %00111111 11111111. That's too big to store in a.
ld a,$40
cp $40
ZF NC Hit zero but didn't set the carry flag.
ld a,0
dec a
ZF CF Dec and inc do not set the carry flag even if a borrow is needed. A is %11111111 now.

* ZF stands for zero flag set, CF stands for carry flag set, NZ stands for zero flag reset, and NC stands for carry flag reset.


Conditions are used in redirection commands. If the condition is true, then the processor goes the the specified address and starts executing code.

Syntax Variations Explaination
jr addr1
jr z,addr1
jr nz,addr1
jr c,addr1
jr nc,add1
jump if zero flag set
jump if zero flag reset
jump if carry flag set
jump if carry flag reset
ret z
ret nz
ret c
ret nc
ret if zero flag set
ret if zero flag reset
ret if carry flag set
ret if carry flag reset
jp addr1
jp z,addr1
jp nz,addr1
jp c,addr1
jp nc,add1
jump if zero flag set
jump if zero flag reset
jump if carry flag set
jump if carry flag reset
call addr1
call z,addr1
call nz,addr1
call c,addr1
call nc,add1
call if zero flag set
call if zero flag reset
call if carry flag set
call if carry flag reset

Check out these branch jumps in action...

	ld a,69			;load a with number
	cp 69			;is a equal to 69?
	jr z,it_was_69		;it was 69!
	jr nz,it_was_not_69	;wouldn't even
				; need this
				; because either
				; the zero flag is
				; set or not
You can also use other registers in checking.
	ld b,69			;number to check
	ld a,69			;number to check against
	cp b			;is a=b?
	jr z,it_is		;they're both the same
	jr nz,it_is_not		;it isn't

More from z80 » Beginner
Aliases // Convert from decimal to hexadecimal or binary // Flags and Conditions // Format and Compiling // Instructions // Math // Number Bases // Oh, No! It Crashed! // Registers // TI-BASIC to Asm Comparisons // TI86 Specifications // Two's Compliment // z80 Processor