Flags and Decision Making
As described in Chapter 6, the Z80 architecture includes six flags, which are flip-flops that are set or reset after the execution of arithmetic and logic operations, with some exceptions. Four of the flags (S, Z, P/V, and CY) can be used by the programmer for decision making in conjunction with Jump and Call instructions; the remaining two (H, N) are used internally by the microprocessor for BCD arithmetic. The thorough understanding of flags is critical to writing assembly language programs.
In many ways the flags are like signs on an interstate highway that help drivers in decision making. A driver sees one or more signs at a time, but continues along the highway ignoring the signs until the appropriate sign is found, and then he or she changes direction or takes an exit. Flags function similarly as signs of data conditions. After an operation, one or more flags are set (or reset) and can be used to change the direction of program sequence by using Jump instructions (discussed in the next section). The following illustrations from Example may clarify some of the critical issues.
1. In Example, Instruction 5 sets the Sign flag and resets the other flags. However, the Sign flag can be ignored because the numbers loaded into registers are unsigned numbers. The Sign flag is relevant when the programmer is dealing with signed numbers.
2. Instruction 7 sets the Carry flag and resets the other flags. If the programmer is adding numbers and is interested in finding the total, the Carry flag must be used to test for a sum larger than an 8-bit number.
3. Another important observation that can be made after the execution of Instruction 7 is that the flags set by Instruction 5 are altered by Instruction 7. Thus, if the programmer is interested in making a decision based on the Sign flag, it should be made before that flag is altered by another operation.
Signed Numbers and Flags
The microprocessor is incapable of understanding a + or – sign unless the sign is represented in the form of binary digits. Therefore, in 8-bit microprocessors, bit D7 is reserved for the sign by the user when signed numbers are used in arithmetic operations. For a positive number, bit D7 is 0, and for a negative number, D7 is set to 1; the remaining seven bits represent the magnitude of a number. If a number is negative, it is represented in 2’s complement. In an 8-bit microprocessor, the largest positive number is 0111 1111 (7FH = + 12710), and the largest negative number is 1000 0000 (80H = -12810).
The Z80 microprocessor has two flags to indicate the status of the arithmetic results in signed numbers: Sign and Overflow. After an arithmetic (or logical) operation, if bit D7 = 1, the Sign flag is set, and if D7 = 0, the Sign flag is reset. However, this flag can be misleading when the result of an addition exceeds the magnitude 7FH or that of the subtraction exceeds 80H. These conditions are known as overflow and are indicated by the P/V flag.
The P/V flag is a dual-purpose flag; in logical operations it indicates parity, and in arithmetic operations it indicates an over flow. In arithmetic operations, if the sum of two positive numbers exceeds 7F, bit D7 becomes 1, indicating a negative number. However, the Z80 sets the P/V flag to indicate the error in the result. The critical point to remember is that the Z80 does not know whether the numbers are signed, unsigned, or just individual digits. The interpretation of the flags is the responsibility of the user.
Example
Add two signed numbers: + 29H and + 76H. Indicate the status of the flags S, P/V, and CY if the operation is performed by the Z80 microprocessor. Explain how. The flags are affected if the numbers are unsigned.
Solution
CY = 0 because the sum does not exceed FFH,
S = 1 because D7 = 1, and
P/V =1 because the sum exceeds 7FH.
In this addition of two positive numbers, the sign flag erroneously indicates that the sum is negative; however, the overflow flag (P/V) suggests that the result has an overflow from bit D6 and that the result is therefore inaccurate. The user must check the P/V flag and correct the sum.
If these numbers were unsigned numbers, the interpretation of the result would therefore be different; the user should ignore the S and P/V flags and check for the CY flag. In this example, the sum is 9FH with no carry.
Another common misunderstanding is that bit D0 in the result 9FH is 1; therefore, bit D0 in the flag register must be 1, thus setting the CY flag. There is no relationship between bit D0 of a result and bit D0 of the flag register.