What an ISA Is
May 16, 2026·25 min read·intermediate
Up to this point we have built a computer from below: gates and flip-flops, registers and ALUs, datapath and control, memory and I/O. Each layer of the construction has hidden the messiness of the…
Up to this point we have built a computer from below: gates and flip-flops, registers and ALUs, datapath and control, memory and I/O. Each layer of the construction has hidden the messiness of the layer below it and presented its successor with a cleaner abstraction. The capstone of this tower of abstractions, the layer at which hardware finally meets software, is the instruction set architecture, almost always abbreviated ISA.
The ISA is the contract between the hardware and the programmer. It specifies what instructions the processor understands, what data it can operate on, what registers and memory it exposes, and what each instruction does in terms a programmer or compiler can reason about. Anything above the ISA — operating systems, compilers, applications — is software, and depends on the ISA's promises. Anything below it — pipelines, caches, branch predictors, voltage regulators — is the implementation, and is free to vary as long as the contract is honored. This chapter examines that contract: what an ISA is, what makes it a good one, and how the major examples differ.
01. The ISA as a Contract
A precise way to think of an ISA is as a specification, expressed in human language and pseudo-code, of an idealized machine. The specification describes:
- The state the machine maintains: how many registers it has, how wide they are, what the address space looks like, what status flags exist.
- The instructions the machine executes: their encoding (which bit patterns mean what), their operands, and their semantics.
- The memory model: the rules for how loads and stores interact, particularly when multiple processors are involved.
- The exception model: how the machine reacts to errors and interrupts (Chapter 15).
- The privilege model: how the machine distinguishes the operating system from ordinary applications (also Chapter 15).
The contract is binding in both directions. Software is permitted to rely on every promise the ISA makes; an instruction whose behavior the ISA specifies must produce that behavior on every processor that claims to implement the ISA. Hardware is permitted to do anything it wants internally as long as the externally observable behavior matches the specification. A modern Intel x86-64 chip and a 1985-vintage 80386 are both x86 processors, with implementations that share almost no transistor-level details, but they execute the same instruction stream and the modern chip is bound to produce the same architectural state the older chip would have produced.
The contract is what allows decades of software to outlast generations of hardware. A program compiled to x86-64 in 2005 still runs on x86-64 chips in 2026. The internals of the chips have been redesigned many times in those two decades — pipelines deepened and shortened, caches enlarged, branch predictors invented and reinvented, vector units widened from 128 bits to 256 to 512 — but the ISA contract has been preserved. This stability is one of the most important properties an ISA can have, and one of the hardest to maintain.
02. What the ISA Specifies
A useful way to enumerate what an ISA covers is to walk through what a programmer writing in assembly language or a compiler emitting machine code needs to know.
Registers. How many general-purpose registers are there, how wide are they, and what (if anything) is special about any of them? RISC-V has 32 integer registers (and an optional 32 floating-point registers), each 64 bits wide on the 64-bit variant; one of them, x0, is hardwired to zero. ARMv8-A has 31 general-purpose registers plus a stack pointer. x86-64 has 16 general-purpose registers, one of them (rsp) functioning as the stack pointer by hardware convention. The ISA specifies all of this.
Data types. What sizes of integer does the machine handle natively (8, 16, 32, 64 bits, sometimes 128)? What floating-point formats does it support (single, double, half, quad)? Does it have vector or SIMD types? Are there decimal types, fixed-point types, or special encodings? An ISA either supports a type, in which case it provides instructions to operate on it, or does not, in which case software must emulate it from smaller pieces.
Instructions. What operations can the machine perform — arithmetic, logical, memory, branch, system? How are they encoded into bits? How are operands specified? RISC-V's instructions are all 32 bits wide (or 16 with the compressed extension); each one fits one of a small number of formats. x86 instructions vary from 1 byte to 15 bytes, with elaborate prefix and ModR/M structures. ARMv8-A instructions are 32 bits (with an optional Thumb-2 encoding). The ISA specifies the bit-level encoding of every instruction, because that is what the hardware actually decodes.
Addressing modes. How can an instruction refer to a memory location? RISC architectures typically allow only register-plus-immediate-offset; CISC architectures historically allowed elaborate combinations of base register, index register, scale, displacement, and segment. Each addressing mode is part of the ISA.
Memory model. When two cores access the same memory, what orderings of their loads and stores are observable? Strong models like x86's TSO require almost-sequential ordering; weak models like ARM's allow many more reorderings; very weak models like RISC-V's RVWMO allow even more. The memory model is part of the ISA — Chapter 31 will treat it in depth.
Exceptions and interrupts. How does the machine indicate that an arithmetic operation overflowed, a memory access faulted, or an interrupt arrived? What state does it save? What handler does it invoke?
Privilege levels. Does the machine distinguish kernel code from user code? Does it have hypervisor or secure-monitor levels? What instructions are restricted to which level?
System interface. How does software invoke operating-system services (the system-call instruction)? How does it manage page tables? How does it configure interrupts? These are usually grouped into the privileged ISA and may be specified in a separate document from the user-level ISA.
A complete ISA specification runs to thousands of pages. The Intel Software Developer's Manual fills four volumes; the ARM Architecture Reference Manual is even longer; the RISC-V specifications, despite being relatively compact, span several volumes when all the extensions are counted.
03. Word Size, Address Width, and Endianness
Three of the most basic decisions an ISA designer makes are the word size, the address width, and the endianness. They sound trivial, but each has propagated through every subsequent decision and every line of every program ever written for the architecture.
The word size is the natural width of the integer registers and the integer ALU. A 32-bit ISA has 32-bit registers; a 64-bit ISA has 64-bit registers. Almost every general-purpose ISA has gone through a transition from a smaller word to a larger one over its lifetime: 8 bits to 16 to 32 to 64 in the x86 family; 32 to 64 in ARM; 32 to 64 in MIPS, SPARC, POWER, and many others. RISC-V's specification is unusual in defining the variants — RV32I, RV64I, and RV128I — simultaneously, with carefully designed differences so that the same software stack can be ported with minimal effort.
The address width is the number of bits in a memory address. It is logically separate from the word size, although in practice the two are usually equal: 64-bit ISAs have 64-bit addresses, 32-bit ISAs have 32-bit addresses, and the few historical mismatches (x86 PAE, AArch64's 52-bit physical addresses) tend to confuse software for years. A larger address space is the single most common reason to grow the word size; the move from 32-bit to 64-bit x86 was driven almost entirely by the 4 GiB ceiling of 32-bit addresses, not by any need for 64-bit arithmetic.
In practice no current 64-bit ISA actually wires up the full 2⁶⁴ bytes of address space. Both x86-64 and AArch64 implement only 48 bits of virtual address (and a varying number of physical-address bits), with the upper bits required to be sign- or zero-extended copies of bit 47. This canonical-address rule reserves the high half of the address space for future growth and gives the kernel a non-overlapping range for its own use. Recent extensions (5-level paging on x86-64, 52-bit virtual on AArch64) gradually widen the implementable range; the canonical rule continues to apply at whatever boundary the implementation supports.
Endianness is the order in which the bytes of a multi-byte value are stored in memory. In little-endian order, the least-significant byte goes at the lowest address; in big-endian order, the most-significant byte goes at the lowest address. The choice has no effect on register-only computation but affects every load and store of multi-byte data, every hex dump of memory, and every binary file or network packet that crosses between machines of different endianness. x86 has always been little-endian; AArch64 and RISC-V default to little-endian but can be configured big-endian on some implementations; older POWER and SPARC defaulted to big-endian. The combination of historical choices and network-protocol conventions (TCP/IP headers are big-endian) means that programmers who deal with binary I/O still routinely write byte-swap macros. A modern ISA pins endianness firmly: software depends on it, and changing it after the fact would break essentially every binary in existence.
04. Operating Modes Within an ISA
Many ISAs are not a single uniform machine but a family of related machines selected by an operating mode. Switching modes changes which instructions are valid, what registers exist, how addresses are formed, and sometimes what privilege level the CPU runs at. The mode is itself part of the architectural state.
x86 is the extreme case. The same physical chip can run in real mode (16-bit, segment-based addressing, the boot environment of every PC), protected mode (32-bit, with paging and segmentation, the mode 32-bit operating systems use), and long mode (64-bit, with x86-64's enlarged register file and simplified segmentation, the mode every modern OS uses). A modern Linux or Windows boot is a sequence of mode transitions: the firmware starts the CPU in real mode, the bootloader switches to protected mode, and the kernel finally switches to long mode. Long mode itself has a compatibility sub-mode in which 32-bit applications can still run under a 64-bit OS, and various legacy sub-modes (virtual-8086, system-management mode) survive for backward compatibility. Each mode is a partly different ISA, and the manual has to specify the behaviour of every instruction in every mode.
ARM had a famously dual-personality 32-bit history. The original A32 instruction set was 32-bit fixed-width; the Thumb sub-mode was a 16-bit re-encoding of a subset; Thumb-2 added 32-bit Thumb instructions to round out the set; ThumbEE was a Java-targeted variant; Jazelle ran some Java bytecode directly. The 64-bit AArch64 mode is essentially a separate ISA from AArch32, with different instruction encodings, a different register file, and different exception model; an implementation may support either or both, and modern Apple silicon supports only AArch64. Within AArch64 the exception level (EL0, EL1, EL2, EL3) plays a similar role to x86's privilege rings.
RISC-V is much simpler: the base ISA defines XLEN-bit operations, where XLEN is 32 in RV32 and 64 in RV64, and a single mode bit selects which on a hardware that supports both (most do not). RISC-V's privileged modes — U, S, M, plus optional H for the hypervisor extension — govern privilege but not the user-mode encoding.
The practical importance of operating modes is that the same bit pattern can mean different things in different modes. The byte 0x66 is an instruction in 16-bit real mode, an operand-size prefix in 32-bit protected mode, and the same prefix in 64-bit long mode. Disassemblers, debuggers, and JIT compilers must know which mode they are in to interpret the bits correctly.
05. Backward and Forward Compatibility
An ISA's promise is that software written today still works tomorrow. Backward compatibility is the property that an old binary continues to run on new hardware; forward compatibility is the harder property that a new binary can detect at runtime which features the hardware actually supports and adapt accordingly. Both are real engineering disciplines that good ISA designs build into the contract.
The foundation of forward compatibility is a feature-discovery mechanism: a way for software to ask the hardware what it can do.
On x86, the CPUID instruction returns a wealth of information: the vendor, the family/model/stepping, and — most importantly — dozens of feature bits identifying which extensions the chip supports. A program that wants to use AVX-512 must check the corresponding CPUID bit before issuing the first AVX-512 instruction; if the bit is clear, the program must fall back to a scalar or AVX2 path. Operating systems publish this information to user space through the same mechanism (or, on Linux, through the auxv AT_HWCAP vector and /proc/cpuinfo).
On AArch64, a small set of system ID registers (ID_AA64ISAR0_EL1, ID_AA64ISAR1_EL1, ID_AA64PFR0_EL1, etc.) report supported features in named bitfields. These registers are normally readable only at EL1 and above, but Linux exposes the relevant bits to user space through the HWCAP and HWCAP2 words in the ELF auxiliary vector.
On RISC-V, the misa CSR identifies the supported base ISA and standard extensions, and the mvendorid, marchid, and mimpid CSRs identify the implementation. As with AArch64, Linux exposes the user-relevant bits through HWCAP. The RISC-V community has also defined profiles (RVA22, RVA23, and so on) that bundle specific sets of extensions into named, versioned targets, so that a binary can declare "requires RVA22" and a system can answer "yes" or "no" without enumerating every extension.
Backward compatibility is achieved by a few discipline rules that every long-lived ISA follows. New instructions are encoded into previously reserved opcode slots, never on top of existing ones. New architectural state is opt-in: a CPU that does not implement a feature simply does not expose it. New control bits in shared registers are reserved-zero until they are defined, and software is required to write zero to them so that the hardware can repurpose them later. Privilege levels and exception handlers are extended rather than redefined.
When these disciplines are violated, the cost is enormous. The original Intel 8086's reuse of certain opcode bytes for the 80286's protected-mode instructions caused decades of confusion. The decision in early x86-64 to keep the legacy floating-point stack alongside SSE for thirty years was driven by binary-compatibility constraints. The careful hands-off-reserved-bits discipline that AArch64 and RISC-V enforce from the start is in large part a reaction to those experiences.
Forward compatibility is also why so much modern software is built with runtime CPU dispatch: critical functions like memcpy, string searching, cryptographic primitives, and SIMD math kernels exist in several versions, and the loader chooses one at startup based on the CPU's reported features. Tools such as glibc's IFUNC, Function Multiversioning in GCC and Clang, and Apple's selectors all implement this pattern. A binary built with dispatch can deliver near-peak performance on modern hardware while still booting on the conservative baseline that the ISA's original specification mandates.
06. Profiles, Extensions, and Modular ISAs
The oldest ISAs accreted features one at a time, with no overall structure. SSE was added to x86 in 1999, SSE2 in 2001, SSE3 in 2004, SSSE3 in 2006, SSE4.1 in 2007, SSE4.2 in 2008, AVX in 2011, AVX2 in 2013, AVX-512 in 2017, AMX in 2021, AVX10 in 2024 — each a separate extension with its own feature bit, its own small or large addition to the encoding space, and its own implications for the rest of the architecture. Software that wants to use any of them must check feature bits at runtime; software that wants to be portable must usually target the lowest common denominator the deployment requires.
Newer ISAs treat extensions as a first-class structural concept rather than an afterthought.
ARM divides its 32-bit family into three profiles: Cortex-A (application processors with full MMU and operating-system support), Cortex-R (real-time profile with predictable timing), and Cortex-M (microcontroller profile with optional MMU and minimal instruction set). The 64-bit AArch64 family currently has a single profile (the application profile) but standardizes its extensions through Architecture Versions — ARMv8.0-A, v8.1-A, ..., v9.4-A — each of which mandates a specific set of new features and forbids implementations from cherry-picking. A chip that claims ARMv8.6-A compatibility implements every required ARMv8.6-A feature.
RISC-V takes modularity further than any other ISA. The base integer ISA (I) is small enough that it can be implemented in a tiny embedded core; standard extensions add multiplication and division (M), atomics (A), single-precision floating-point (F), double-precision (D), quad-precision (Q), compressed instructions (C), bit manipulation (B), vectors (V), cryptography (K), hypervisor (H), and many more. The naming convention RV64IMAFDC (often abbreviated RV64GC, where G stands for IMAFD) describes what a chip implements. To prevent the combinatorial explosion this would otherwise produce, the RVA profile family fixes specific bundles — RVA20, RVA22, RVA23 — each of which is a moving target for application processors, with a defined set of mandatory and optional extensions. A binary built for RVA22 runs on any chip that claims RVA22; a fragmented set of extensions is no longer a portability nightmare.
A profile is therefore the higher-level organizing concept that an ISA exposes to software. Software targets a profile rather than a specific chip; chips claim conformance to one or more profiles; the ISA's evolution moves the set of profiles forward over time.
07. Open and Proprietary ISAs
A last dimension worth naming explicitly is the legal status of the ISA. An ISA is, technically, a body of intellectual property: a collection of published documents, names, and (sometimes) patents. The terms under which others may build implementations of the ISA are part of the architecture's broader story, even if they never appear in the architecture manual.
x86 is proprietary. Intel and AMD hold extensive patent portfolios covering the ISA and its implementations, cross-license those portfolios with each other, and license selectively to a handful of other vendors (historically VIA, Cyrix, Transmeta, Zhaoxin). Building an x86 chip without one of those licenses is not legally feasible. This has constrained the supplier base to two main vendors for most of the architecture's history.
ARM is licensed. ARM Holdings (now a subsidiary of SoftBank) sells two main classes of license. An architecture license lets the licensee design its own implementation of the ISA from scratch; this is the route Apple, Qualcomm (for their custom cores), Nvidia, and others take. A core license lets the licensee integrate ARM's pre-designed Cortex-A, Cortex-R, or Cortex-M cores into a chip, typically more cheaply but with less flexibility. ARM's terms have been adjusted over time, often controversially, but the fundamental model has been stable: pay ARM, build a chip.
RISC-V is open. The specification is published under a permissive license, and anyone may build a compliant implementation without paying royalties or asking permission. Compliance is a self-attestation, with optional certification through the RISC-V Compliance Working Group. The result is an unusually broad supplier base: large vendors (SiFive, Andes, Codasip), academic research projects, open-source cores (Rocket, BOOM, CVA6), commercial chips from Esperanto, Tenstorrent, Ventana, and many others, and dozens of in-house designs that never become products. The same openness extends to the toolchain: the LLVM, GCC, and binutils implementations of RISC-V support are upstream and freely available.
The distinction matters because it shapes the ecosystem around the ISA. A proprietary ISA tends to have fewer, larger, more vertically integrated vendors and a tightly controlled extension process. An open ISA tends to have many smaller vendors, more rapid experimentation, and a corresponding risk of fragmentation that profiles are designed to contain. Neither model is universally better; both have produced commercially successful chips. But the legal status is part of the architectural picture, and a working architect should know it.
08. ISA versus Microarchitecture
The single most important conceptual distinction in this part of the book — and perhaps in all of computer architecture — is the distinction between the architecture (the ISA) and the microarchitecture (its implementation).
The architecture is what the programmer sees. It is the set of registers, instructions, and behaviors that programs are written against.
The microarchitecture is how a particular chip implements the architecture. A microarchitecture decides how many stages the pipeline has, how many instructions can be issued per cycle, how the cache is laid out, what branch predictor is used, how registers are physically realized (often through register renaming, where the architectural register r5 is mapped to dozens of physical storage locations at different points in time).
A given ISA can be implemented by many microarchitectures. The x86-64 ISA has been implemented by Intel's Pentium, Pentium 4, Core, Sandy Bridge, Skylake, Sunny Cove, Golden Cove, and many other microarchitectures, by AMD's K7, K8, Bulldozer, Zen, Zen 2, Zen 3, Zen 4, and Zen 5, and by older third-party microarchitectures from Cyrix, VIA, and Transmeta. Each is a different chip, with different internals and different performance, but each runs x86-64 code.
A useful analogy is a programming-language standard. The C language is defined by an ISO standard; gcc, clang, MSVC, and many other compilers implement it. The standard is the architecture; the compilers are microarchitectures. They differ in optimization, code quality, and quirks, but a program that adheres to the standard runs on all of them.
This distinction has practical consequences. When you read that a new processor offers "20 % more IPC than the previous generation," that is a microarchitectural improvement. The ISA is unchanged; the implementation is faster. When a new ISA extension is added — say AVX-512, or Arm's SVE, or the RISC-V V extension — that is an architectural change, and software has to be rewritten or recompiled to take advantage of it. ISA changes are rare and slow; microarchitectural changes happen with every new generation.
09. Designing an ISA
Designing a good ISA is one of the more interesting problems in computer architecture, because the constraints pull in different directions and many of them are visible only over decades.
A good ISA is expressive enough. Compilers must be able to translate high-level languages into it efficiently. Instructions that real programs need — integer arithmetic, comparisons, branches, calls, memory accesses, floating-point operations — must be present and reasonably efficient.
A good ISA is simple enough. Every instruction must be implementable in hardware, ideally efficiently and without obscure corner cases. Complex instructions that take hundreds of cycles or require microcode often turn out, in retrospect, to have been a bad bet.
A good ISA is regular. Instructions should have consistent encodings, consistent operand formats, and consistent semantics. Irregularity makes both compilers and decoders harder to write. The original VAX, for example, was designed around the principle that everything should be possible — any instruction could use any addressing mode for any operand — but the resulting machine was so irregular that high-performance implementations were nearly impossible to build.
A good ISA is stable. Software lifetimes outlast hardware lifetimes, and changing an ISA breaks a great deal. Successful ISAs evolve by extension — adding new instructions while keeping old ones working — rather than by replacement.
A good ISA is efficient to encode. Instruction encodings consume memory and instruction-cache space; a denser ISA can fit more code into the cache, which improves performance. RISC-V's compressed instruction extension and ARM's Thumb-2 are both responses to this concern.
A good ISA is forgiving of microarchitectural evolution. Some ISAs make certain microarchitectural techniques much harder. Self-modifying code, for example, was historically supported on x86 because of its CISC heritage, and modern implementations pay a real cost in pipeline complexity to keep it working. RISC ISAs typically require the programmer to issue an explicit fence before executing recently-modified code, which simplifies the hardware.
These goals conflict. A more expressive ISA tends to be less simple; a more regular one tends to be less compact; a more stable one tends to accumulate cruft over decades. Real ISAs are compromises among these forces, and the compromises are different for different application domains. An embedded ISA can be much simpler than a server ISA, because it does not need to support the entire history of an operating system.
10. A Brief Tour of Real ISAs
A quick survey of the ISAs you are likely to encounter in practice will help anchor the abstract discussion.
x86 and x86-64. The dominant desktop, laptop, and server ISA. Originally an 8-bit CISC architecture from Intel (the 8080 and 8086 of the late 1970s), extended over time to 16, 32, and 64 bits, with hundreds of additional instruction extensions: MMX, SSE, SSE2, AVX, AVX2, AVX-512, BMI, AES-NI, SHA-NI, AMX, and more. Variable-length encoding (1 to 15 bytes), large register-and-memory addressing modes, complex semantics for many instructions, two operating modes (x86 with 32-bit registers, x86-64 with 64-bit registers and twice as many of them). Architecturally complex but extremely backwards-compatible.
ARM and ARM64 (AArch64). The dominant ISA for phones, tablets, and increasingly servers and laptops. A clean RISC design, originally 32-bit (now called AArch32) and now in a 64-bit variant (AArch64) that is essentially a separate ISA. Fixed 32-bit instructions, 31 general-purpose registers, simple addressing modes, weak memory model. AArch64 is widely considered one of the cleanest production ISAs, having had the benefit of fifty years of architecture experience to draw on.
RISC-V. A clean-slate open ISA developed at UC Berkeley starting in 2010. Fixed 32-bit instructions in the base ISA (with optional 16-bit compressed encodings), 32 general-purpose registers, register-plus-offset addressing only, very weak memory model. Modular: the base ISA defines integer arithmetic and memory access, and optional extensions add multiplication and division, atomics, single- and double-precision floating point, vector instructions, and so on. Open in the sense that the specification is freely usable; there are commercial and open-source implementations.
MIPS. A pioneering RISC architecture from the 1980s, hugely influential in academic teaching but largely retired commercially. Almost every textbook example of a RISC processor (including the famous one in Patterson and Hennessy) is MIPS-based.
SPARC. Sun Microsystems' RISC ISA, used in Sun and Oracle servers from the 1980s to the 2010s. Now mostly historical.
POWER and PowerPC. IBM's RISC ISA, still widely used in IBM's mainframe-class servers. The original Apple Macintoshes used PowerPC; Apple has since migrated through x86 to its own ARM-based silicon.
z/Architecture. IBM's mainframe ISA, descended from the System/360 of 1964 and still going strong. A fascinating example of how ruthlessly an ISA can preserve compatibility while evolving — code from the 1960s still runs on modern z/Architecture machines with minor changes at most.
The two great ISA families today are x86-64 (descended from CISC) and ARM/RISC-V (descended from RISC). The next chapter examines what those terms mean and why the distinction, while less stark than it once was, still matters.
11. Why ISAs Persist
A natural question is why old ISAs survive at all. If x86-64 is so awkward and AArch64 is so clean, why does x86-64 still dominate servers? If we know what we know now, why does anyone build new chips for ISAs designed decades ago?
The answer is the software ecosystem. An ISA without software is useless; an ISA with billions of lines of working software is enormously valuable. A new ISA, no matter how technically superior, has to overcome the inertia of every operating system, compiler, library, and application that targets the existing ones. That inertia is so large that complete replacement of an ISA is rare. The transition from 32-bit x86 to x86-64 took fifteen years; the transition from PowerPC to x86 on Macs took several years; the transition from x86 to AArch64 on Macs took a few years more, made smoother by Apple's controlled software stack and a binary translation layer. Server transitions are slower still.
The corollary is that ISA decisions are extremely high-stakes. A design choice baked into an ISA in 1978 can still be paying interest in 2026. The "high memory" gymnastics of MS-DOS, the segment registers of x86-32, the historical half-register pairs of x86 — all are consequences of decisions made decades ago that the ISA can never fully discard.
The lesson for ISA design is to be conservative: simple, regular, extensible, with a clean separation between the user-level core and optional features, and with a well-defined story for how the ISA can grow. RISC-V and AArch64 have learned this lesson. x86-64 is paying the cost of having been designed before the lesson was clear.
12. Summary
The instruction set architecture is the layer of the system at which hardware and software meet. It specifies the registers, instructions, data types, memory model, exception model, and privilege model that programs see, and it is binding on every implementation. Every ISA also fixes a word size, an address width, and an endianness, and many ISAs run in several distinct operating modes — x86's real, protected, and long modes, ARM's AArch32 and AArch64, RISC-V's RV32 and RV64 — each of which is partly a different machine. Backward compatibility is sustained by strict reserved-bits discipline; forward compatibility is enabled by feature-discovery mechanisms (CPUID on x86, ID registers on AArch64, misa and HWCAP on RISC-V) and by runtime CPU dispatch in critical libraries. The same ISA can be implemented by many microarchitectures of vastly different internal complexity and performance, and software written to the ISA runs on all of them. A good ISA balances expressiveness, simplicity, regularity, stability, encoding efficiency, and friendliness to microarchitectural evolution; modular extensions, profiles, and architecture-version bundles let the ISA grow without fragmenting its software ecosystem. The major real ISAs in use today — x86-64, AArch64, RISC-V, POWER, z/Architecture — represent different points on these tradeoff axes, and they differ further in their legal status, from x86's tightly licensed duopoly through ARM's licensed-but-broad ecosystem to RISC-V's royalty-free openness, each shaping the supplier base and the pace of innovation around it.
In Chapter 12 we will examine the most famous of these tradeoffs — RISC versus CISC — and see how the once-bitter divide between them has softened into something more nuanced.