How the CMP Instruction Updates CPU Flags
The CMP (Compare) instruction evaluates the relationship
between two operands by performing an internal, implicit subtraction
without saving the mathematical result to any destination register.
Instead of overwriting register contents, the processor routes the
output of the Arithmetic Logic Unit (ALU) directly to the status
register (such as the FLAGS or EFLAGS register in x86 architecture). By
observing the resulting status flags—primarily the Zero Flag (ZF), Sign
Flag (SF), Carry Flag (CF), and Overflow Flag (OF)—subsequent
conditional jump instructions can determine whether the first operand
was equal to, greater than, or less than the second operand while
keeping the original binary data intact.
The Binary Subtraction Mechanism
At the hardware level, the ALU performs subtraction using two’s
complement arithmetic. When a program executes CMP A, B,
the processor calculates \(A - B\) by
converting \(B\) into its two’s
complement form (inverting all bits of \(B\) and adding \(1\)) and then adding that value to \(A\):
\[\text{Result} = A + (\sim B + 1)\]
During a standard SUB A, B instruction, the ALU
completes this operation and writes the resulting binary value back into
the register holding operand \(A\). The
CMP instruction uses the identical ALU circuitry to perform
this exact binary addition, but it disables the write-back stage of the
CPU pipeline. The output data bus simply discards the arithmetic result,
leaving operand \(A\) and operand \(B\) completely unmodified.
Evaluating and Updating Status Flags
Even though the numerical difference is discarded, the characteristics of the calculation are captured and latched into the processor’s flag register. The primary flags updated by the implicit subtraction include:
- Zero Flag (ZF): The ALU sets
ZF = 1if every bit of the subtraction result is zero, which occurs exclusively when \(A = B\). If any bit in the result is non-zero,ZF = 0. - Sign Flag (SF): The processor sets
SFto match the most significant bit (MSB) of the result. In signed two’s complement notation, an MSB of1represents a negative value (\(A < B\)), while an MSB of0indicates a non-negative value (\(A \ge B\)). - Carry Flag (CF): Used for unsigned comparisons, the
Carry Flag acts as an inverted borrow indicator. If \(A < B\) in an unsigned context, the
operation requires a borrow, setting
CF = 1. If \(A \ge B\), no borrow occurs, andCF = 0. - Overflow Flag (OF): Used for signed comparisons,
OFis set to1if the subtraction generates a result that exceeds the maximum or minimum representable value for the signed integer size (e.g., subtracting a negative number from a positive number produces a negative result due to wraparound).
Execution Flow and Conditional Branching
By altering only the status flags, CMP acts as a
non-destructive probe into the system’s state. Conditional jump
instructions (such as JE for Jump if Equal, JL
for Jump if Less, or JA for Jump if Above) immediately
evaluate these flag combinations to alter execution flow. For example,
JE branches if ZF = 1, while JL
branches if the Sign Flag does not equal the Overflow Flag (\(SF \neq OF\)). This separation of
arithmetic evaluation from data modification allows programs to make
control-flow decisions efficiently without requiring temporary registers
to store calculation results.