x86 的 ud2 指令为何叫 ud2?
Why is the x86 undefined instruction called ud2? Why 2?
在查看 x86 编译器输出或调试 API 重定向导致的崩溃时,你常会看到 ud2 指令。这是一条架构上未定义的指令,用于触发“无效操作码”异常,防止程序执行随机代码。但为什么它叫 ud2 而不是 ud?难道存在 ud1?事实上,早期开发者曾利用 0F FF 和 0F B9 等字节序列来触发异常,分别被 retroactively 命名为 ud0 和 ud1。后来 Intel 发现这些序列的行为不可靠,受 Hyrum's Law 影响,最终正式定义了 ud2 作为标准的未定义指令。ud2 的优势在于它是一条无参数的双字节指令,行为一致且架构保证,避免了因解码问题引发的访问违规。
只要有足够多的用户,所有可观察的行为都会被某人依赖。
HN 评论区
62- hacker_homie
0F FF 的拥趸们终于得到了回报,他们获赐了 UD0 操作码的殊荣,使其成为唯一且真正的原始无效操作码,而 0F B9 的追随者们则永远蒙羞,只能顶着 UD1 的名号。
- 349ru3h4f03
如今,UD0、UD1 和 UD2 都已收录在 SDM 和 APM 中。
我们还拥有了 UDB(D6),这是随 x86-64 推出的单字节变体,专用于 64 位模式。
而 UDW(FF FF)我们一直都有,也就是第 5 组(第一个 FF),其 modrm 字节为 mod=11b, r/m=111b (/7), reg=111b(第二个 FF)——这条指令在内存所有位均为 1 时很重要,或者当总线终止于全 1 且没有设备响应访问时也很重要。
- gtirloni
我最近不得不调试一些随机失败的构建,结果发现 V8 抛出的 ud2 就在那里等着我。
- Neywiny
我不太熟悉 x86,但在其他架构上你可以触发软件中断/异常。难道 x86 没有这个功能,还是说这些设施覆盖的使用场景不够多?
- ordu
“之所以叫 ud2,是因为 0F FF 变体被回溯命名为 ud0,而 0F B9 变体被回溯命名为 ud1,因此 ud2 成为了推荐的未定义操作码。”
作为读者,这对我来说是个意外。读到这句话时,我原本以为 0f ff 会变成 #1,而 0fb9 变成 #2。但并没有,Intel 是从零开始计数的,所以实际上存在第三个 ud。