ASSEMBLY LANGUAGE - WEEK VIII				December 21, 1986


FLAGS


The Flag register is an 8-bit register that contains individual "flag" bits that are automatically set and reset by the Z-80 to represent the status of a particular, predefined condition. The flag register may also be referred to as the STATUS or CONDITION CODE register. The bits of the flag register are important because they may be tested by a group of "conditional" instructions provided for the Z-80. The ultimate action such a conditional instruction takes will be dictated by the status of a corresponding flag at the time the instruction is actually executed. These instructions endow the computer with ability to make "decisions".

The Z-80 CPU is provided with six basic "flags". 


The flags contained in the F register and their bit positions are shown in the figure below:


Bit:     7     6     5     4     3     2     1     0



Flag:    S     Z     -     H     -    P/V    N     C





          S   = SIGN FLAG

          Z   = ZERO FLAG

          H   = HALF CARRY FLAG

          P/V = PARITY/OVERFLOW FLAG

          N   = ADD/SUBTRACT FLAG

          C   = CARRY FLAG

Bits 3 and 5 of the flags register are not used ("-"). We say that a flag is set if it has a value of 1 or reset if it has a value of  zero. Four bits of the Flag register can be used to control program flow. 
The results of addition and subtraction operations can be characterized from the status of the four flags (C, P/V, Z, S). The status of these flags can be tested and all branching executed within a program will jump to specified locations depending on the status of these flags. The status of the flags in conjunction with conditional jump, conditional call, and conditional return instructions can be used to make decisions in the program. There are two common procedures for making decisions:
 1) Branching if two values are equal or not equal
 2) Branching if one value is greater or less than another


The four flags involved in decision making are the Carry flag, the Zero flag, the Sign flag, and the Parity/Overflow flag. 
The other two flags H and N are used for BCD arithmetic and cannot be tested. 

It is important to understand the role of the various flags available, since the real power of a program will depend on its decision making capability. Most decisions taken within the program will be taken as a function of these flag bits.



Branching based on equality uses the Zero flag. The Zero (Z) flag refers to a bit that can indicate if the value of the accumulator or other associated register is exactly equal to zero. It is also used with comparison instructions to indicate a match. Compare instructions (CP) are more useful than subtract instructions (SBC or SUB) because compares preserve the value in the accumulator for later operations. The Compare instruction (CP) performs a subtraction, but the result is not saved. If the value in the accumulator is compared to another value by subtraction (remember comparison is a subtraction) and the result is zero, the Z flag will be set to "1" indicating the values are equal. Z is reset to "0" otherwise. Note, however, that the Z-80 has a 16-bit subtract with borrow instruction (SBC HL), but no 16-bit compare or subtract instructions.


Branching based on Magnitude comparisons:

Branching based on Magnitude comparisons can involve the Carry (C) flag, the Sign (S) flag, and the Parity/Overflow (P/V) flag.

Before we discuss flags, let's discuss numbers.

We can use the byte in the Z-80 to represent two kinds of numbers: 
	1) Binary (Absolute) numbers
	2) Signed numbers

Binary (Absolute) numbers

Absolute numbers are always positive. Earlier we mentioned that in eight bits the binary values 00000000 through 11111111 could be held and that these represented 0 through 255 decimal. Similarly, 16 bit numbers represent values from sixteen zeros to sixteen ones, or decimal 0 through 65535.
We have been working with hexadecimal numbers, which are really a shorthand way of representing binary numbers that have been grouped in 4-bit groups. 

Absolute numbers in binary (hexadecimal) can be used to represent memory addresses, counts, or any quantity that will never be negative. 

Signed Numbers

Many applications require only positive numbers, and in these situations a number's sign need not be considered. There are, however, many applications that involve both positive and negative numbers, and in these situations, the Z-80 must be able to accommodate both. When an application includes both positive and negative numbers, each number must be signed either + or -. Since the Z-80 is organized around 8-bit byte wide numbers the sign must occupy one of those eight bits. the most significant bit (D7) is designated the sign bit and when one is using signed numbers it represents only the sign of the number. 

Since one bit of a byte is now dedicated to the sign, the quantity must be represented in only seven bits, D0-D6. A signed number can, therefore, fall in the range of +127 to -128. When the sign bit is 0 the associated number is positive, when the sign bit is 1 the associated number is negative. 

The Z-80 automatically examines the sign of the numbers created by the arithmetic/logic operations and sets a flag in the F register to indicate positive or negative results. The Z-80 does not have any special instructions for dealing with signed numbers. All of the instructions used to this point can be used with signed numbers except DAA. 
Although there are no special Z-80 instructions for handling signed numbers there is a signed carry flag in the F register to aid the programmer.

 All signed operations depend on the interpretation of data by the programmer and the programs developed. 

Magnitude Comparisons

In a magnitude comparison, we determine if the value in the accumulator is greater than or less than some other value by subtraction. The SBC is used when an operation may generate a sum greater than 255 or a difference smaller than 1. If, as is typical, the values are unsigned, the Carry (C) flag indicates which is larger.

If the sum of two numbers exceeds 255, then the result will be too large to fit in into the 8 bit accumulator. The carry flag will be set to reflect this overflow. During subtraction, the carry flag is set when a larger number is subtracted from a smaller one. In this case,the flag becomes and indication that borrowing has taken place. 

In general, 
. Carry = 1 if the value subtracted is larger than the value in the accumulator (that is, if a borrow is required).

. Carry = 0 if the value in the accumulator is larger or if the two values are equal.

A magnitude comparison between signed numbers does not use the Carry bit, but uses the Sign (S) and the Parity/Overflow (P/V) flags. If the values are signed, we must allow for the possible occurrences of two's complement overflow. This is the situation in which the difference between the numbers cannot be contained in seven bits and,therefore, the sign bit is changed. For example, if one number is +7 and the other is -125, the difference is -132, which is beyond the capacity of eight bits (it is less than -128, the most negative number that eight bits can hold).

If overflow is a possibility, we can determine if it occurred by examining the Parity/Overflow flag after the addition or subtraction instruction. If that flag is 1, overflow did occur. The mnemonics here are confusing, since the Parity/Overflow flag normally indicates whether the result has even parity; the branches are therefore PE (Parity even, or Overflow Set) and PO (Parity Odd or Overflow Clear).

 Thus, in the case of signed numbers, we must allow for the following possibilities:
. The result has the sign (positive or negative, as shown by the Sign flag) that we want, and the Parity/Overflow flag indicates that the sign is valid.

. The result does not have the sign that we want, but the Parity/Overflow flag indicates that the two's complement overflow has changed the real sign. 

The carry flag in the F register cannot be interpreted to represent carries developed during signed operations. The C flag is set on carries from bit 7 but bit 7 is used to represent a number's sign, not its most significant bit. The parity/overflow flag is set if an arithmetic operation produces a carry or borrow out of bit 6, the most significant bit in a signed number. The P/V flag is set if an arithmetic operation produces a carry or borrow out of bit 6 and is reset if a carry or borrow is not produced. Of course, if a carry or borrow out of bit 6 occurs, it changes bit 7. If bit 7 is changed, the number's sign is changed.  Interpretation of the P/V and S flags is not as straightforward with signed numbers.


There are some cases in which overflow cannot occur and all we must do is use the Sign flag instead of the Carry flag for branching. These cases are the following:

. The two numbers have the same sign. When this occurs, the difference is smaller in magnitude than the larger of the two numbers and overflow cannot occur. 

. A value is being compared to Zero. In this case, the Sign flag must be set and examined.



At this point, it is only necessary to remember the main function of each of these bits. When programming, the reader can refer to the description of the instruction to verify the effect of every instruction of the various flags. Most flags can be ignored most of the time, and the reader who is not yet familiar with them should not feel intimidated by their apparent complexity. Their use will become clearer as we examine more application programs.

    