When you are debugging a microcontroller on the bench, reading raw hex dumps or logic analyzer traces requires instant mental translation between decimal and binary. While floating-point math is handled by dedicated FPUs, the core Arithmetic Logic Unit (ALU) in almost every modern microcontroller—from the ATmega328P in an Arduino Uno to the Xtensa cores in an ESP32—relies on integer binary math. Understanding how the hardware handles negative numbers is non-negotiable for embedded systems work.

Below is a complete walkthrough of an exam-style problem. This provides a rigorous, practical example of binary number system arithmetic, specifically focusing on two's complement addition and the status flags that dictate conditional branching in assembly and C code.

The Practice Problem: 8-Bit Two's Complement Addition

Exam Problem Statement:
An 8-bit microcontroller ALU is instructed to add two signed integers. Register A holds decimal -54, and Register B holds decimal +117.
  1. Convert both values to 8-bit two's complement binary.
  2. Perform the binary addition, tracking all carries.
  3. Determine the final 8-bit result in decimal.
  4. Identify the state of the Carry (C) and Overflow (V) status flags in the ALU status register.

Before solving, we must establish the positional weights of an 8-bit register. The method applied here is the Radix-2 positional numeral system combined with two's complement encoding. We use two's complement because it allows the ALU to use the exact same hardware adder circuit for both addition and subtraction, eliminating the need for a separate subtractor.

Bit Position Power of 2 Unsigned Weight Signed Weight (Two's Complement)
7 (MSB)2^7128-128
62^66464
52^53232
42^41616
32^388
22^244
12^122
0 (LSB)2^011

Step-by-Step Solution: Algebra, Bitwise Math, and Flag Logic

We will break this down into the exact algebraic and bitwise steps the ALU performs. For deeper background on binary addition rules, refer to the All About Circuits digital textbook.

Step 1: Convert +117 to 8-Bit Binary

Since 117 is positive, its two's complement representation is identical to its standard unsigned binary form. We subtract the largest powers of 2 that fit into 117:

  • 117 - 64 = 53 (Bit 6 = 1)
  • 53 - 32 = 21 (Bit 5 = 1)
  • 21 - 16 = 5 (Bit 4 = 1)
  • 5 - 4 = 1 (Bit 2 = 1)
  • 1 - 1 = 0 (Bit 0 = 1)

Result for +117: 01110101

Step 2: Convert -54 to 8-Bit Two's Complement

To represent a negative number, we follow a strict three-step algebraic process:

  1. Find the absolute value in binary: +54 = 32 + 16 + 4 + 2 → 00110110
  2. Calculate the One's Complement (invert all bits): 11001001
  3. Calculate the Two's Complement (add 1 to the LSB):
    11001001 + 00000001 = 11001010

Result for -54: 11001010

Step 3: Perform Binary Addition

Now we feed both 8-bit registers into the ALU adder. We must track the carry bit moving from right (LSB) to left (MSB).

  Carries: 11000000
           --------
           01110101  (+117)
         + 11001010  (-54)
         ----------
         1 00111111  (9-bit raw result)

The ALU discards the 9th bit (the carry out of the MSB) because it is an 8-bit register, leaving the final 8-bit result: 00111111.

Step 4: Determine the Status Flags

Microcontrollers like the AVR (used in Arduino) store arithmetic metadata in the Status Register (SREG). We need to evaluate two specific flags:

  • Carry Flag (C): This is the carry-out from the MSB (Bit 7). Looking at our addition, Bit 7 generated a carry of 1. Therefore, C = 1.
  • Overflow Flag (V): This indicates if a signed operation exceeded the valid range (-128 to +127). The hardware calculates this by XORing the carry into the MSB with the carry out of the MSB. Here, the carry into Bit 7 was 1, and the carry out was 1. Since 1 XOR 1 = 0, V = 0.

The Trap: Carry vs. Overflow in Signed Binary Arithmetic

⚠ The Exam & Bench Trap:
The most common mistake students and junior firmware engineers make is confusing the Carry (C) flag with the Overflow (V) flag.

The Carry flag is strictly for unsigned math. It tells you if your result exceeded 255. The Overflow flag is strictly for signed math. It tells you if your result exceeded +127 or dropped below -128.

In our problem, C=1 but V=0. If you are writing assembly or optimizing C code for a motor controller and you use a "Branch if Carry Set" (BRCS) instruction to check for a signed math error, your code will falsely trigger an error routine. You must use "Branch if Overflow Set" (BRVS) when dealing with signed two's complement variables. For a deeper dive into CPU flag logic, review the Kansas State University binary math module.

Independent Verification and Sanity Checks

Never trust a binary conversion on an exam or in a critical firmware routine without an independent sanity check. Here is how we verify our answer.

1. Decimal Equivalence Check

Let's convert our final 8-bit binary result (00111111) back to decimal using the unsigned weights (since the MSB is 0, it is a positive number):

32 + 16 + 8 + 4 + 2 + 1 = 63

Does this match our original decimal algebra?
(+117) + (-54) = 117 - 54 = 63.
The math holds up perfectly.

2. Order of Magnitude and Units Sanity Check

  • Order of Magnitude: 117 is roughly 10^2. 54 is roughly 10^1. The difference should be in the 10^1 range (tens). Our answer, 63, is exactly in the 10^1 range. If we had missed a bit and gotten 191 or 3, the order of magnitude would immediately flag an error.
  • Units: Dimensionless integer counts. No scaling factors were applied.
  • Range Check: The result (+63) easily fits within the 8-bit signed range of -128 to +127, confirming our V=0 flag calculation is physically logical.

Frequently Asked Questions

Why not just use a sign-magnitude system instead of two's complement?
Sign-magnitude (where the MSB is just a negative sign) creates two representations for zero (+0 and -0) and requires complex, separate hardware for addition and subtraction. Two's complement guarantees a single zero and allows the ALU to simply add the binary strings together regardless of sign, vastly simplifying silicon design.

What happens to the 9th bit (the Carry out) in actual hardware?
It isn't deleted; it is latched into the Carry (C) flag in the status register. In multi-byte addition (like adding two 32-bit integers on an 8-bit AVR), the next instruction uses an "Add with Carry" (ADC) opcode to pull that 9th bit into the next byte's LSB, chaining the math across registers.