Lesson 3. Negative numbers and subtraction: two's complement

In pictures

After this lesson the same adder learns to subtract: the SUB switch turns A + B into A − B. Four lamps show the flags — what the processor knows about every answer: was there a carry, is the answer zero, is it negative and did it fit in 4 bits.


3.1. The idea: numbers on a circle

A 4-bit adder counts in a circle: 15 + 1 gives 0 — the fifth digit goes into the carry. So 1111 behaves like −1: add 1 to it and you get 0. In the same way 1110 is −2 and 1000 is −8.

Let us agree: if the top bit is 1, the number is negative. Then 4 bits hold the numbers from −8 to 7. This way of writing is called two's complement. Nothing in the adder has to change: it adds bits, and what they mean is up to us.

00000000110010200113010040101501106011171000-81001-71010-61011-51100-41101-31110-21111-1+1 — one stepclockwisetop bit 0 — numbers 0…7top bit 1 — numbers −8…−11111 + 1 = 1 0000in 4 bits: −1 + 1 = 0−3: flip and +10011 → 1100 → 11010111 + 1 = 10007 + 1 = "−8": overflow V
Four bits are a circle of 16 numbers: +1 is one step clockwise, after 1111 comes 0000 again. If numbers with the top bit 1 count as negative, 1111 is −1 and 1000 is −8. The adder is the same — only the way we read the bits changes.

How to get −B: flip all the bits of B and add 1. For example, 3 = 0011 → 1100 → 1101 = −3. Check: 3 + (−3) = 0011 + 1101 = 1 0000 — zero in 4 bits.

And subtracting means adding −B:

  • XOR with the SUB switch flips the bits of B: with SUB = 0 a bit passes as it is, with SUB = 1 it is flipped;
  • the "plus 1" comes from the same SUB fed to the carry input CI of the adder.
SUB=1B0=1bx0=0B1=0bx1=1B2=1bx2=0B3=0bx3=1ADDER4A + bx + CICIA = 0011S = 1110= −2, N is lit0011 + 1010 + 1= 1110
The ADDSUB4 subtractor for 3 − 5. SUB = 1 flips the bits of B in the XOR gates (0101 → 1010) and adds one through CI: 3 + 1010 + 1 = 1110, that is −2. With SUB = 0 the XOR gates pass B as it is and CI = 0 — plain addition.

3.2. Flags

After an addition or a subtraction every processor keeps four bits about the answer:

  • C (carry) — the carry out of the top digit. When subtracting, C = 1 means "no borrow": A ≥ B unsigned;
  • Z (zero) — the answer is zero: all digits are 0, that is a NOR of all the bits;
  • N (negative) — the answer is negative: simply the top bit of the sum;
  • V (overflow) — the answer did not fit in the signed numbers: both operands have the same sign and the sum the other one. For example, 7 + 1 gives 1000 — "−8".

The processor decides by these flags: "if zero — jump", "if less — repeat".

3.3. Building

The same project. Delete the lesson 2 setup (8 switches, ADDER4 on the canvas, three displays); keep Power/Ground.

The idea. Subtracting B means adding −B. In two's complement −B = all the bits of B flipped, plus 1. XOR with the SUB switch does the flipping (with SUB = 0 a bit passes as it is, with SUB = 1 it is flipped), and the "plus 1" comes from the same SUB on the carry input CI of the adder.

Step 1. ADDSUB4 — addition and subtraction

PartPinLabel
Input portoutA0
Input portoutA1
Input portoutA2
Input portoutA3
Input portoutB0
Input portoutB1
Input portoutB2
Input portoutB3
Input portoutSUB
Input portoutCI
XOR (bit 0)I0
I1
O0
B0
SUB
bx0
XOR (bit 1)I0
I1
O0
B1
SUB
bx1
XOR (bit 2)I0
I1
O0
B2
SUB
bx2
XOR (bit 3)I0
I1
O0
B3
SUB
bx3
ADDER4A0
A1
A2
A3
B0
B1
B2
B3
CI
S0
S1
S2
S3
CO
A0
A1
A2
A3
bx0
bx1
bx2
bx3
CI
S0
S1
S2
S3
CO
XOR (sign A ≠ sign S)I0
I1
O0
A3
S3
va
XOR (sign B ≠ sign S)I0
I1
O0
bx3
S3
vb
AND (overflow)I0
I1
O0
va
vb
V
Output portinS0
Output portinS1
Output portinS2
Output portinS3
Output portinCO
Output portinV

Ctrl+G → name ADDSUB4. Pins: inputs A0–A3, B0–B3, SUB, CI; outputs S0–S3, CO, V.

V is overflow: both operands have the same sign and the sum has the other one (so 7 + 1 gives "−8").

Step 2. Canvas: switches, subtractor, flags

PartPinLabel
InputoutA0
InputoutA1
InputoutA2
InputoutA3
InputoutB0
InputoutB1
InputoutB2
InputoutB3
InputoutSUB
ADDSUB4A0
A1
A2
A3
B0
B1
B2
B3
SUB
CI
S0
S1
S2
S3
CO
V
A0
A1
A2
A3
B0
B1
B2
B3
SUB
SUB
S0
S1
S2
S3
C
V
ORI0
I1
O0
S0
S1
z01
ORI0
I1
O0
S2
S3
z23
NOR (zero)I0
I1
O0
z01
z23
Z
LED (C — carry)inC
LED (Z — zero)inZ
LED (N — sign)inS3
LED (V — overflow)inV
Display⚙width 4, DEC, bus A
Display⚙width 4, DEC, bus B
Display⚙width 4, BIN, bus S

The subtractor's CI goes to the same label SUB: that is the "plus 1". Lamp N is simply the top bit of the sum S3.

3.4. Check

Negative numbers in 4 bits: 1111 = −1, 1110 = −2 … 1000 = −8. The top bit is the sign.

ASwitches A3…A0BSwitches B3…B0SUBDisplay SLampsMeaning
300114010000111—3 + 4 = 7
300115010111110N3 − 5 = −2
501015010110000Z, C5 − 5 = 0
200103001111111N2 − 3 = −1 (C = 0: a borrow)
701111000101000N, V7 + 1 does not fit in 4 signed bits
910019100100010C, V−7 + −7 = −14 — also an overflow

In the "Switches" columns the top switch (A3) is on the left and A0 on the right; 1 — on, 0 — off.

When subtracting, C is lit when there was no borrow (A ≥ B unsigned) — as in most processors, the 6502 for one.

If with SUB = 1 the answer is one less, check that the subtractor's CI is on the label SUB, not on GND.


Lesson 3 paste (Cmd+I)

Needs XOR, AND, OR, NOR and ADDER4. Delete the lesson 2 setup, keep the power.

# Lesson 3 — two's complement subtraction and the flags C, Z, N, V.chip ADDSUB4 {  portIn(A0)  portIn(A1)  portIn(A2)  portIn(A3)  portIn(B0)  portIn(B1)  portIn(B2)  portIn(B3)  portIn(SUB)  portIn(CI)  portOut(S0)  portOut(S1)  portOut(S2)  portOut(S3)  portOut(CO)  portOut(V)  XOR(B0, SUB, bx0)  XOR(B1, SUB, bx1)  XOR(B2, SUB, bx2)  XOR(B3, SUB, bx3)  ADDER4(A0=A0, A1=A1, A2=A2, A3=A3, B0=bx0, B1=bx1, B2=bx2, B3=bx3, CI=CI, S0=S0, S1=S1, S2=S2, S3=S3, CO=CO)  XOR(A3, S3, va)  XOR(bx3, S3, vb)  AND(va, vb, V)} input(A0)input(A1)input(A2)input(A3)input(B0)input(B1)input(B2)input(B3)input(SUB)ADDSUB4(A0=A0, A1=A1, A2=A2, A3=A3, B0=B0, B1=B1, B2=B2, B3=B3, SUB=SUB, CI=SUB, S0=S0, S1=S1, S2=S2, S3=S3, CO=C, V=V)OR(S0, S1, z01)OR(S2, S3, z23)NOR(z01, z23, Z)led(C)led(Z)led(S3)led(V)

¿No te sale? Algo no funciona →