Why is the x86 undefined instruction called ud2? Why 2?
Raymond Chen unravels the curious tale behind the x86 ud2 instruction, explaining why this "undefined" opcode isn't simply ud or ud1. It's a classic Old New Thing dive into hardware history, highlighting how developers' reliance on unofficial behavior forced Intel to standardize a guaranteed crash instruction. HN readers will appreciate this deep technical history lesson on CPU design quirks and backward compatibility.
The Lowdown
Raymond Chen, the venerable Windows historian, takes us on a journey through the evolution of the x86 ud2 instruction, revealing why this seemingly arbitrary name was chosen and the architectural headaches it solved. This deep dive illuminates the messy reality of processor design, where unofficial behaviors become de-facto standards.
- Purpose of
ud2: Theud2instruction is an architecturally undefined opcode designed to reliably trigger an "invalid opcode" exception, commonly used by compilers to mark unreachable code segments. - Pre-
ud2Era: Initially, x86 had no official undefined instruction. Developers discovered that0F FF(later retroactively namedud0) and0F B9(retroactivelyud1) reliably caused invalid opcode exceptions. - Hyrum's Law Strikes: As Intel evolved its processors, changes potentially altered the behavior of
0F FFand0F B9, breaking applications that had come to rely on their undefined nature. This exemplified Hyrum's Law: "With a sufficient number of users, all observable behaviors will be depended upon by somebody." - Birth of
ud2: Recognizing the need for a stable, architecturally guaranteed undefined instruction, Intel officially introducedud2to provide consistent behavior. - Advantages of
ud2: Unlike its predecessors,ud2is a clean two-byte instruction without any associated parameters. This avoids issues likeud0andud1internally decoding unused parameters, which could inadvertently lead to access violations if the decoding process crossed into unmapped memory pages. - Inconsistent Legacy: Older processors even exhibited inconsistent behavior with
ud0/ud1at page boundaries, sometimes raising an invalid opcode exception and sometimes an access violation.
Ultimately, ud2 stands as a testament to the complex interplay between hardware evolution, developer reliance on observed behavior, and the need for standardized, predictable mechanisms, even for signaling unpredictable execution.