x86 的未定义指令为什么叫 ud2:从 ud0 与 ud1 说起
来源: devblogs.microsoft.com — 2026-09-10
概述
Raymond Chen 解释了编译器输出与崩溃现场里那个熟悉的 ud2 从何而来。它是一条架构上永久未定义的指令,保证触发「非法操作码」异常,编译器常用它标记不可达代码——比如标了 [[noreturn]] 的函数真的返回时就撞上它。历史上 x86 并没有官方未定义指令,于是大家各找字节序列:一派用 0F FF,一派用 0F B9。Intel 在后续处理器上运行旧软件时发现程序依赖了这些序列的异常行为,正应了 Hyrum 定律,索性把它们正式收编:0F FF 追认为 ud0、0F B9 追认为 ud1,真正推荐的未定义指令便是 ud2。它的好处是两字节且不带参数,不会像前两者那样「解码但不使用」操作数——如果指令解码跨入不存在的页,你等来的不是非法操作码异常而是访问违例。
核心要点
- ud2 是架构保证的未定义指令,编译器用它标记不可达代码,让流程走到这里就崩溃而不是继续执行随机指令。
- ud0/ud1 这些名字是事后追认的:0F FF 被追认为 ud0,0F B9 被追认为 ud1,真正的推荐指令因此才是 ud2。
- 命名顺序的成因是 Hyrum 定律:一旦有足够多用户,所有可观察行为都会被依赖,Intel 只能把这些字节序列合法化。
- 带参数是坑:即使处理器不使用操作数,它仍然要解码;跨页解码时得到的是访问违例而不是非法操作码。
金句
更好的做法是坚持用 ud2——它的行为一致,而且由架构保证。
👍 0
👎 0
返回 Lobsters 首页