Intuition What this page is for
The parent note taught you the rules for the four flags. But rules only stick when you have seen every trap . This page is a scenario matrix : a grid of every situation the ALU can face, then one worked example per cell. By the end you will never meet an input pattern you haven't already practised.
Everything here is 8-bit (n = 8 ). Two ranges to keep in mind, and we will earn both:
Unsigned (all patterns are ≥ 0 ): 0 … 255 .
Signed (top bit means "minus"): − 128 ⋯ + 127 — this is two's complement .
Before the matrix, let us re-anchor the four flags in plain words + one picture so nothing below uses a symbol you haven't met.
Picture the 8 bits as 8 boxes in a row , numbered from the right: box 0, box 1, … up to box 7 on the far left. Box 7 is special — it is the top box (MSB) .
Definition The four flags, re-stated
Z (Zero) — is every box a 0? Then Z = 1 . It is a "are we empty?" alarm.
N (Negative) — just a wire copied from box 7 . If box 7 is lit, N = 1 . Only means "negative" when we agreed to read the number as signed.
C (Carry) — did a "1" fall off the left edge past box 7 during addition? On subtraction it is the inverted borrow (we build this below). It answers the unsigned question.
V (Overflow) — did the signed answer leave the range − 128 … 127 ? It answers the signed question, and it is a different question from carry.
Every ALU flag puzzle is one of these cells. The goal: hit all of them below.
#
Cell (the situation)
What's being tested
Example
A
Add, both small positives
clean case, all flags calm
Ex 1
B
Add, unsigned carry but signed is correct
C=1, V=0 (independent!)
Ex 2
C
Add, signed overflow but no carry
C=0, V=1 (independent!)
Ex 3
D
Add, negatives that overflow (neg+neg→pos)
C=1 and V=1 together
Ex 4
E
Subtract, A < B (borrow / negative result)
subtract carry = borrow logic
Ex 5
F
Subtract, A ≥ B , result positive
subtract carry = "no borrow"
Ex 6
G
Subtract equal values → zero (degenerate)
Z=1 on subtract, x − x = 0
Ex 7
H
Logic op (AND / XOR) — flags behave differently
C and V forced to 0
Ex 8
I
Shift left — the "carry catches the falling bit"
C from shifted-out bit
Ex 9
J
Real-world + exam twist (sensor wraparound)
apply flags to a decision
Ex 10
Ten cells, ten examples. Every numeric answer at the bottom is machine-checked.
A = 18 , B = 3 (8-bit)
Forecast: before reading on, guess all four flags. (Both numbers are tiny and positive — do you expect any flag lit?)
Write both in binary. 18 = 0001 0010 , 3 = 0000 0011 .
Why this step? Flags are computed from bits , not decimals, so we must see the boxes.
Add column by column: 0001 0010 + 0000 0011 = 0001 0101 .
Why this step? This is the actual adder output; 0001 0101 = 21 .
Z : any box lit? Yes (boxes 0,2,4). So Z = 0 .
Why this step? Z is NOR of all bits; a single 1 kills it.
N : box 7 is 0, so N = 0 .
Why this step? N is literally the top box.
C : nothing fell off the left, c 8 = 0 , so C = 0 .
Why this step? 18 + 3 = 21 < 256 , unsigned fits.
V : pos + pos gave pos, sign never flipped, V = 0 .
Why this step? Carry into box 7 = 0, carry out = 0, 0 ⊕ 0 = 0 .
Verify: 18 + 3 = 21 , and 0001 010 1 2 = 21 . Both signed (21 ) and unsigned (21 ) readings agree — a calm result has all flags 0. ✓
A = 255 , B = 1 (8-bit)
Forecast: signed, 255 is really − 1 . So this is − 1 + 1 . Guess: which flag lights, C or V?
Binary: 255 = 1111 1111 , 1 = 0000 0001 .
Why this step? 1111 1111 is all boxes lit — the classic "about to wrap" pattern.
Add: 1111 1111 + 0000 0001 = 1 0000 0000 . Keep 8 boxes → 0000 0000 .
Why this step? The 9th "1" cannot be stored; it falls off the left edge.
C : a 1 fell off → c 8 = 1 , so C = 1 .
Why this step? Unsigned 255 + 1 = 256 > 255 , out of unsigned range.
Z : every box is 0 → Z = 1 .
Why this step? NOR over all-zero bits is 1.
N : box 7 is 0 → N = 0 .
V : carry into box 7 was c 7 = 1 , carry out was c 8 = 1 , and 1 ⊕ 1 = 0 , so V = 0 .
Why this step? They agree , so no signed overflow. Signed view: − 1 + 1 = 0 — exactly right!
Verify: unsigned 256 mod 256 = 0 ; signed − 1 + 1 = 0 . Result is 0 , C = 1 , V = 0 : a big unsigned carry with a perfectly correct signed answer . C and V are independent . ✓
A = 127 , B = 1 (8-bit)
Forecast: signed max is + 127 . What is 127 + 1 supposed to be, and can 8 signed bits hold it? Guess C and V.
Binary: 127 = 0111 1111 , 1 = 0000 0001 .
Why this step? 0111 1111 is the largest positive signed value — box 7 empty, all others full.
Add: 0111 1111 + 0000 0001 = 1000 0000 .
Why this step? The carry ripples up and lands inside box 7, flipping it to 1.
N : box 7 is now 1 → N = 1 .
Why this step? The sign bit flipped from + to −.
C : did anything leave box 7? No, c 8 = 0 , so C = 0 .
Why this step? Unsigned 127 + 1 = 128 ≤ 255 , fits fine unsigned.
V : carry into box 7 was c 7 = 1 (that's what flipped it), carry out c 8 = 0 . 1 ⊕ 0 = 1 , so V = 1 .
Why this step? Signed answer should be 128 , but max signed is 127 ; it wrapped to − 128 . Overflow!
Verify: result 1000 0000 = 128 unsigned = − 128 signed. 127 + 1 = 128 = − 128 , so signed is wrong → V = 1 . Unsigned 128 is correct → C = 0 . Mirror image of Example 2. ✓
A = − 100 , B = − 50 (8-bit signed)
Forecast: true sum − 150 . Signed range bottom is − 128 . Can it hold − 150 ? Guess both flags.
Encode in two's complement. − 100 : 100 = 0110 0100 , invert = 1001 1011 , + 1 = 1001 1100 . − 50 : 50 = 0011 0010 , invert = 1100 1101 , + 1 = 1100 1110 .
Why this step? The adder only understands bit patterns; we must convert both negatives via invert-and-add-1.
Add: 1001 1100 + 1100 1110 = 1 0110 1010 . Keep 8 → 0110 1010 .
Why this step? Two "big" patterns add past 8 boxes, so a 1 falls off the left.
C : a 1 fell off → c 8 = 1 , so C = 1 .
Why this step? Unsigned view: 156 + 206 = 362 > 255 .
N : box 7 of 0110 1010 is 0 → N = 0 .
Why this step? Two negatives produced a positive-looking result — the classic overflow tell.
V : carry into box 7? Adding box-7 bits 1 + 1 plus incoming carry 0 gives 10 , so c 7 = 0 into box 7... let us use the sign rule instead: neg + neg → the result's sign came out positive (N = 0 ). Sign flipped wrongly → V = 1 .
Why this step? "Same signs in, sign flips out = overflow." Both inputs negative, output positive → overflow.
Verify: 0110 1010 = 106 signed. But − 100 + − 50 = − 150 , and − 150 wrapped: − 150 + 256 = 106 . Signed answer wrong (V = 1 ), unsigned carry happened (C = 1 ). Both flags lit at once. ✓
First, let us build the subtract-carry rule so no symbol is unearned.
Intuition What "borrow" means, with a picture
Subtraction is done as A − B = A + ( ∼ B ) + 1 , where ∼ B means "flip every box of B " and the + 1 arrives as carry-in . This is the same adder reused. The carry-out of this addition is the flag C — but on subtraction we read it as: C = 1 ⇒ no borrow (A ≥ B ); C = 0 ⇒ a borrow happened (A < B ).
A − B with A = 3 , B = 5
Forecast: 3 − 5 = − 2 . Since A < B , will C be 1 or 0?
∼ B : B = 0000 0101 , flip → ∼ B = 1111 1010 .
Why this step? Turns subtraction into an addition the ALU already knows.
Add with carry-in 1: 0000 0011 + 1111 1010 + 1 = 1111 1110 .
Why this step? The "+1" completes the two's-complement negation of B .
R = 1111 1110 . As signed: invert → 0000 0001 , + 1 → 0000 0010 = 2 , so value = − 2 .
Why this step? Reading a two's-complement negative back to decimal.
C : carry out of box 7 here is 0 → C = 0 → borrow occurred .
Why this step? 3 < 5 , so subtraction had to borrow; the ALU signals that via C = 0 .
N : box 7 is 1 → N = 1 (negative). Z : not zero → Z = 0 .
V : pos − pos = pos + neg (opposite signs) → cannot overflow → V = 0 .
Why this step? Opposite-sign additions never leave signed range.
Verify: 3 − 5 = − 2 , matches. C = 0 correctly flags "A < B " — this is exactly the test a `BCC` (branch if carry clear) uses for unsigned <. ✓
A − B with A = 200 , B = 80
Forecast: 200 − 80 = 120 ≥ 0 , and A ≥ B . Guess C .
B = 80 = 0101 0000 , ∼ B = 1010 1111 .
Why this step? Prepare the addition form.
A = 200 = 1100 1000 . Add: 1100 1000 + 1010 1111 + 1 = 1 0111 1000 . Keep 8 → 0111 1000 .
Why this step? A 1 falls off the left → that becomes the carry.
R = 0111 1000 = 120 .
Why this step? Box 7 empty → positive; 64 + 32 + 16 + 8 = 120 .
C : carry out = 1 → no borrow → confirms A ≥ B (unsigned 200 ≥ 80 ).
Why this step? On subtract, C = 1 is the "greater-or-equal" signal.
N = 0 (box 7 empty). Z = 0 . V : 200 and 80 are unsigned here; signed-wise 200 = − 56 , so − 56 − 80 = − 136 would overflow... but we asked for the unsigned subtraction interpretation. As pure signed: − 56 − 80 = − 136 < − 128 ⇒ V = 1 . Interpretation matters — see below.
Why this step? Same bits, two stories: unsigned answer 120 is right (C = 1 ), but if these were signed numbers, V = 1 warns the signed answer wrapped.
Verify: unsigned 200 − 80 = 120 (result bits give 120, C = 1 ). Signed − 56 − 80 = − 136 , which is < − 128 so V = 1 . The ALU sets both C and V ; you pick which to read based on whether you meant signed or unsigned. ✓
A − B with A = B = 64
Forecast: 64 − 64 = 0 . Which flags must fire?
B = 64 = 0100 0000 , ∼ B = 1011 1111 .
Why this step? Standard subtract prep.
Add: 0100 0000 + 1011 1111 + 1 = 1 0000 0000 . Keep 8 → 0000 0000 .
Why this step? x + ∼ x + 1 = 2 8 , which is exactly a 1 that falls off leaving all zeros.
Z : all boxes 0 → Z = 1 .
Why this step? This is the case Z exists for; equality tests (CMP then BEQ) rely on it.
C : carry out = 1 → no borrow → A ≥ B (indeed equal).
Why this step? A = B counts as "≥ ", so C = 1 is correct.
N = 0 (box 7 empty). V : opposite-sign form, V = 0 .
Verify: 64 − 64 = 0 → Z = 1 , C = 1 , N = 0 , V = 0 . This is precisely how `CMP A,B; BEQ` decides "are they equal?" — it subtracts and checks Z . ✓
A ⊕ B (XOR) with A = 1100 1010 , B = 1010 0110
Forecast: XOR has no notion of "spilling over". Guess C and V .
XOR box-by-box (1 where the boxes differ ):
1100 1010 ⊕ 1010 0110 = 0110 1100 .
Why this step? XOR is bitwise; there is no carry chain between boxes at all.
R = 0110 1100 = 108 .
Why this step? 64 + 32 + 8 + 4 = 108 .
Z : some boxes lit → Z = 0 . N : box 7 is 0 → N = 0 .
Why this step? Logic ops do still set Z and N from the result.
C = 0 , V = 0 — forced .
Why this step? Nothing crosses box boundaries in a logic op, so carry and signed-overflow are meaningless; most ISAs clear them.
Verify: 0 x C A ⊕ 0 x A 6 = 0 x 6 C = 108 . C = V = 0 by definition of a logic op. Contrast with arithmetic ops where C/V carry real information. ✓
LSL (logical shift left by 1) of A = 1011 0010
Forecast: every box slides one step left; box 7 has nowhere to go. Where does it land?
Slide left, feed 0 into box 0:
1011 0010 ≪ 1 = 0110 0100 (box 7's old value falls off the left).
Why this step? Shift-left multiplies by 2; the top box overflows the register.
C : the bit that fell off box 7 was 1 → C = 1 .
Why this step? On shifts, C catches the shifted-out bit — this is how a multi-byte number shifts across words (the carry chains into the next byte's RCL).
R = 0110 0100 = 100 .
Why this step? 64 + 32 + 4 = 100 .
Z = 0 , N = 0 (box 7 now empty).
Why this step? Shifts still set Z and N from the result.
Verify: A = 1011 0010 = 178 ; 178 × 2 = 356 = 256 + 100 , so keeping 8 bits gives 100 and the lost 256 shows up as C = 1 . ✓
Worked example A temperature sensor stores its reading in an
8-bit unsigned register (valid 0..255 ). It reads 250 , then rises by 10 . The firmware does ADD reg, #10 and branches on the carry flag to trigger a "SENSOR SATURATED" warning. Does the warning fire, and what value does the register hold?
Forecast: 250 + 10 = 260 . Register max is 255 . Guess the stored value and C .
250 = 1111 1010 , 10 = 0000 1010 .
Why this step? Convert to bits to run the real adder.
Add: 1111 1010 + 0000 1010 = 1 0000 0100 . Keep 8 → 0000 0100 = 4 .
Why this step? 260 > 255 , so a 1 falls off the left → wraparound.
C = 1 → the BCS (branch if carry set) fires → warning triggers .
Why this step? C is the unsigned out-of-range signal, exactly what "sensor maxed out" means.
Register now holds 4 , a nonsense low value — the wraparound hazard.
Why this step? Without checking C , firmware would think temperature dropped to 4. The flag is the only surviving record of the lost 9th bit.
Exam twist: if the same registers were signed , would you read V instead? 250 signed = − 6 , 10 signed = 10 ; − 6 + 10 = 4 , which fits [ − 128 , 127 ] → V = 0 . Opposite signs can't overflow.
Why this step? Same bits, different flag matters: unsigned firmware watches C , signed logic watches V .
Verify: ( 250 + 10 ) mod 256 = 4 , and 260 ≥ 256 ⇒ C = 1 (warning). Signed reading − 6 + 10 = 4 , in range ⇒ V = 0 . The flags register holds both; the branch chosen decides which one steers the code. ✓
Recall Did we hit every cell?
A→Ex1, B→Ex2, C→Ex3, D→Ex4, E→Ex5, F→Ex6, G→Ex7, H→Ex8, I→Ex9, J→Ex10. Signs covered: pos+pos, neg+neg, pos−pos both directions, mixed. Degenerate zero covered. Logic and shift (where C/V change meaning) covered. Real-world wraparound covered. ✓
Recall When two examples have identical bits but different flags, what decides?
The interpretation you chose (signed vs unsigned) ::: The bits and all four flags are computed the same way every time; you pick C for unsigned decisions and V for signed decisions. The ALU never assumes.
Given A = 127 , B = 1 , 8-bit ADD: which flag is set and which is clear? V = 1 (signed overflow), C = 0 (no unsigned carry).
On a subtract, what does C = 0 tell you about A and B ? A borrow happened, i.e. A < B (unsigned).
For XOR, why are C and V forced to 0? No bit crosses a box boundary in a logic op, so carry and signed-overflow are meaningless.