Follow an addition instruction through a computer
Distinguish unsigned carry from signed overflow with an eight-bit model, then connect bit representations, adders, ISA semantics, and processor execution.
Explain the result pattern, carry, and signed overflow separately, and distinguish the teaching model from a real CPU.
Adding one in a computer involves several layers. A program requests a calculation, an instruction set specifies its visible result, and processor circuitry changes machine state. Separating these layers explains why Python can produce 256 while an eight-bit teaching model produces zero.
We will first examine carry and overflow for fixed-width integers, then connect them to an instruction. This offline model is neither a RISC-V emulator nor a description of a particular CPU's circuitry or timing.
How bits represent integers
A bit has two states. An n-bit unsigned integer represents values from zero to 2ⁿ−1. With eight bits, the range is zero to 255. The highest bit has weight 128 and the lowest has weight one. Reading the same bit pattern under a different representation can produce a different number.
Eight-bit two's-complement integers range from −128 to 127. The pattern 10000000 means 128 when unsigned and −128 in two's complement. Signed and unsigned values are interpretations of bits, not necessarily separate sets of physical digits in a circuit.
Keeping only the low n bits is equivalent to taking the result modulo 2ⁿ. This explains wrapping but does not make wrapping acceptable in an application. Overflow in a balance, inventory count, or array length usually needs rejection, a wider representation, or a defined error.
From Boolean operations to an adder
A one-bit full adder takes two input bits and a carry-in, then produces a sum bit and a carry-out. XOR expresses differing bits; AND and OR can combine conditions that produce carry. Connecting these units gives a model in which carry passes through successive positions.
Real hardware can use more elaborate carry structures. Transistors implement logic gates, gates form combinational circuits, and storage elements such as registers retain state. A software expression a + b does not mean the processor literally calls an eight-step software function.
A clock coordinates some state changes. It does not mean every instruction takes exactly one cycle. Processor design, cache behavior, and dependencies affect execution. There is no universal cycle count without a specific processor and measurement conditions.
Carry and signed overflow answer different questions
The full result of 255 + 1 is 256. Keeping eight bits produces zero and a carry beyond the highest bit. Interpret the inputs as two's-complement values, however, and they are −1 and 1. Their sum is zero, without signed overflow.
The low eight bits of 127 + 1 are 10000000. Unsigned 128 remains representable, so there is no carry into a ninth bit. Under two's-complement interpretation, the result is −128. Two nonnegative inputs have produced a negative result because the signed sum exceeds the representable range.
Before using a shortcut such as checking whether the result is smaller than an input, specify the width, representation, and operation. Languages may define truncation, exceptions, arbitrary precision, or other behavior. A mathematical expression alone does not establish program semantics.
What an instruction specifies
An instruction set architecture, or ISA, defines instruction encodings, registers, and visible operation semantics. RV32I has 32-bit integer registers. Its ADD instruction retains the low XLEN bits; arithmetic overflow does not automatically raise an exception for this instruction. The carry calculation in our teaching model does not imply that RISC-V has a general arithmetic-flags register.
A conceptual execution path is to fetch an instruction using the program counter, decode it, read source registers, perform the operation, write the destination register, and determine the next instruction location. Loading data into a register and adding register values are separate operations.
A real CPU may pipeline instructions, predict branches, or adjust internal execution order under architectural constraints. Visible ISA behavior and internal implementation are different layers. Caches support data access without changing the specified arithmetic result. Performance analysis needs evidence from a particular program and machine.
Model eight-bit results explicitly in Python
Python integers do not have the eight-bit restriction used here. The example computes the full total and uses & 255 to retain eight bits. carry checks the unsigned range. overflow checks whether equal-sign inputs produced a result with a different sign.
def add8(a, b):
assert 0 <= a < 256 and 0 <= b < 256
total = a + b
value = total & 255
carry = total > 255
overflow = bool((~(a ^ b) & (a ^ value)) & 128)
return value, carry, overflow
assert add8(255, 1) == (0, True, False)
assert add8(127, 1) == (128, False, True)
assert add8(1, 2) == (3, False, False)
print(add8(255, 1), add8(127, 1))
The output is (0, True, False) (128, False, True). The returned integer uses unsigned interpretation. The third value concerns addition when those same patterns are interpreted as two's-complement integers. This code neither sets processor flags nor reads actual registers.
Assertions check the example's inputs. An application boundary must not use assertions as its only validation because Python can remove them in optimized execution. Real interfaces should explicitly check types and ranges and produce defined errors.
Exercise: expose both interpretations
Add a function that interprets an eight-bit value as two's complement. Return the value unchanged when its highest bit is clear; otherwise return value − 256. Display signed and unsigned interpretations for both example additions.
Check conversions of zero, 127, 128, and 255, along with positive, negative, mixed-sign, and overflowing additions. Describe the result pattern, carry, and signed overflow separately rather than combining them under one error label.
Then make the width a parameter n and derive the mask 2ⁿ−1 and sign bit 2ⁿ⁻¹. Preserve input checks and the distinction between fixed-width semantics and actual hardware. The model still provides no CPU power, timing, or complete-execution measurements.
Sources & further reading
Sources checked on 2026-11-10. Original engineering explanation; examples are teaching data, not production measurements.