Why x86's undefined instruction is ud2 — and the ghosts of ud0 and ud1
The x86 ud2 instruction exists to fail on purpose: it’s an architecturally guaranteed invalid opcode that compilers drop into unreachable code, so that if execution ever reaches it, the program crashes cleanly instead of running whatever bytes happen to follow. A common use is after a call to a [[noreturn]] function — if the function unexpectedly returns, ud2 stops it from falling through into the next function.
The ‘2’ is a historical fossil. Before Intel offered any official trap instruction, developers hunted for byte sequences that reliably raised an invalid-opcode exception and settled on two rivals: 0F FF and 0F B9. Both worked, so both got used in the wild. When Intel later reworked a processor and those sequences stopped reliably faulting, real software broke — a textbook case of Hyrum’s Law, where every observable behavior eventually becomes something’s dependency. Rather than fight it, Intel blessed a proper permanently-invalid instruction, ud2, and retroactively named the two old sequences ud0 (0F FF) and ud1 (0F B9).
The practical win is reliability. ud2 is a clean two-byte instruction with no operands, so it avoids the edge cases that plague its predecessors: because ud0 and ud1 decode phantom register/memory operands, an instruction sitting at a page boundary could trigger an access violation instead of an invalid-opcode exception when decoding spills into a not-present page — and some older CPUs faulted inconsistently depending on how far they got. ud2’s behavior is architecturally guaranteed and consistent, which is exactly what you want from an instruction whose entire job is to crash predictably.
Read the full article
Continue reading at Hacker News →This is an AI-generated summary. Read the original for the full story.