How Do CPU Status Flags Control Conditional Branching?

Status flags are single-bit indicators stored in a processor's status register that record the outcome of arithmetic and logical operations. By checking the state of the zero, carry, overflow, and negative flags, conditional branch instructions determine whether a program should continue executing sequentially or jump to a different instruction address.

The Role of the Status Register

In classical computing architectures, the Arithmetic Logic Unit (ALU) performs mathematical and bitwise operations on binary data. Alongside producing a numerical result, the ALU updates a special hardware register known as the status register, flag register, or condition code register. Each bit in this register represents a specific condition about the most recent operation.

Because the CPU executes instructions one after another by default, conditional branching requires a mechanism to evaluate comparisons. Rather than storing the entire result of a comparison, the processor relies on these compact status flags to make control-flow decisions.

The Four Core Status Flags

Zero Flag (Z)

The zero flag is set to \(1\) when the result of an operation is exactly \(0\), and cleared to \(0\) otherwise. It is most commonly used to test for equality. When a processor compares two values \(A\) and \(B\) by computing \(A - B\), the zero flag becomes \(1\) if and only if \(A = B\).

Negative or Sign Flag (N / S)

The negative flag mirrors the most significant bit (MSB) of the result. In two's complement representation, an MSB of \(1\) indicates a negative number, while an MSB of \(0\) indicates a non-negative number. If an \(n\)-bit result has a value \(R\), the negative flag is set when \(R < 0\) in signed interpretation.

Carry Flag (C)

The carry flag records whether an unsigned arithmetic operation produced a carry-out from the most significant bit during addition, or required a borrow during subtraction. For an \(n\)-bit unsigned addition \(A + B\), the carry flag is set to \(1\) if the true sum exceeds \(2^n - 1\). In unsigned comparisons, the carry flag indicates whether one number is greater than or less than another.

Overflow Flag (V / O)

The overflow flag indicates that a signed arithmetic operation produced a result too large or too small to fit within the available \(n\)-bit two's complement range, which spans from \(-2^{n-1}\) to \(2^{n-1} - 1\). Overflow occurs when adding two positive numbers yields a negative result, or when adding two negative numbers yields a positive result.

How Instructions Set and Read Flags

Conditional branching typically happens in two distinct steps:

  1. Comparison or Arithmetic Operation: An instruction such as CMP (Compare) or SUB (Subtract) executes. The CMP instruction subtracts the second operand from the first (\(A - B\)) solely to update the status flags, discarding the numerical difference.
  2. Conditional Branch Instruction: A subsequent branch or jump instruction inspects one or more flags to decide whether to alter the Program Counter (PC). If the condition is met, the PC is loaded with the target address; otherwise, execution proceeds to the next instruction in memory.

Combining Flags for Signed and Unsigned Comparisons

While checking equality only requires the zero flag, determining relative magnitude requires different flag combinations depending on whether the data is treated as signed or unsigned.

  • Equal (BEQ / JZ): Branches if \(Z = 1\).
  • Not Equal (BNE / JNZ): Branches if \(Z = 0\).
  • Unsigned Greater Than or Equal: Branches if the carry flag indicates no borrow occurred.
  • Signed Less Than (BLT / JL): Branches if \(N \neq V\). Even if an operation overflows and flips the sign bit, comparing the negative flag against the overflow flag preserves the true mathematical relationship between the two signed operands.
  • Signed Greater Than (BGT / JG): Branches if \(Z = 0\) and \(N = V\).

Through this two-step mechanism of setting flags and evaluating them, classical processors implement high-level control structures such as if-else statements, for loops, and while loops directly in hardware.