Fallacy: More Instructions Always Mean More Power
A common assumption is that an instruction set with a larger number of specialized instructions is inherently more capable than one with fewer, simpler instructions. In reality, a small set of well-chosen primitives, like the RISC-V core instructions covered throughout this chapter, can express any computation a larger, more complex instruction set can, simply by combining more of them together. The tradeoff is not capability, but how many instructions a given task requires and how simple the hardware decoding it needs to be.
Fallacy: High-Level Code Maps One-to-One with Machine Instructions
It is tempting to assume that each line of source code becomes roughly one machine instruction. As the sort example and the arrays-versus-pointers comparison demonstrated earlier in this series, a single high-level statement can expand into several instructions, and the exact number depends heavily on the specific code pattern used, the compiler, and the optimization choices made.
Pitfall: Ignoring Register Limitations When Reasoning About Performance
Because registers are few and extremely fast while memory is abundant and comparatively slow, code that appears simple at the source level can still perform poorly if it forces the compiler to repeatedly move values between memory and registers. Recognizing this tradeoff, discussed earlier when comparing registers and memory, is essential for reasoning correctly about real-world performance rather than just instruction count.
Pitfall: Assuming Signed and Unsigned Numbers Behave Identically
Since signed and unsigned numbers can share the exact same bit pattern but mean different values, comparing or performing arithmetic on them without accounting for their representation, as covered earlier regarding two's complement, is a frequent and subtle source of bugs, particularly at the boundaries of a number's representable range.
Chapter Summary: What Ties Everything Together
Across this chapter, a consistent theme emerges: hardware achieves flexibility not through complexity, but through a small number of simple, regular building blocks — fixed instruction formats, a limited set of arithmetic and logical operations, a small register file, and disciplined conventions for procedure calls — combined in enormous numbers to build everything from a basic sorting routine to a full operating system.
Every concept introduced, from binary number representation to atomic synchronization instructions, exists to serve one underlying goal: allowing software written by people, in human-readable languages, to be translated reliably into a form that simple, fast, physical hardware can execute correctly.