x86 长模式特定指令在保护模式下可用吗?

Jor*_*yen 2 x86 assembly protected-mode disassembly

嘿,我想知道一些仅在长模式下有效的指令。

例如0f 20 55 - mov rbp, cr2

我正在引用 ref.x86asm.net xml 映射
根据xml,该指令的操作方式是e

e 适用于 64 位模式。不考虑SMM。第63章

现在,如果我查看GCCcapstone等反汇编程序,字节流0f 20 55将被解码为mov ebp, cr2保护模式,即使参考文献说它不应该在 x64 以外的模式下可用。

所以我想知道我是否不理解某些东西或者这些反汇编程序有问题?

har*_*old 6

在保护模式和长模式下可以进行控制寄存器的移动,使用相同的编码,但具有不同的含义mov rbp, cr2仅在长模式下可用(显然,它写入仅存在于长模式下的64位GPR)并且mov ebp, cr2仅在保护模式下可用(在长模式下本质上不是不可能的,但其编码被重用于mov rbp, cr2,就像编码一样ofpush eax被重新用来表示push rax)。根据模式的不同,反汇编程序会以不同的方式正确解释相同的机器代码。

  • @Jorayen:关键是,你必须知道你处于什么模式来解释任何操作码。 (4认同)
  • @Jorayen我认为最一致的解释是“如果你将其编码为64位代码,然后将其解码为32位代码,你会得到具有不同含义的东西”。在“mov rbp, cr2”的情况下,含义的差异很小,在其他情况下,它可能很大,例如“movsxd”变成“arpl”。 (3认同)
  • @Jorayen 我相信 GCC 和 capstone 是错误的(并且 Visual Studio 中的反汇编器不同意它们)。无论是否沮丧,带有 32 位目标寄存器的 movsxd 版本都存在,默认情况下 movsxd 没有 64 位操作数大小。在我的 PC 上,执行具有负源的 32 位“movsxd”会清除目标的高 32 位,因此它被解释为 32 位指令。但不要相信我的话,这是一个奇怪的边缘情况。 (3认同)
  • @Jorayen:现在我已经测试了它,是的,这就是它的作用。所以这可以说是那些反汇编程序中的一个错误。gdb 说 `movslq (%rbx),%esi` 我认为是正确的。 (3认同)
  • @Jorayen:英特尔手册称这种编码是“不鼓励的”:https://www.felixcloutier.com/x86/movsx:movsxd。据我所知,它应该被反汇编为 `movsxd esi, dword ptr [rbx]`,即它将 32 位值“符号扩展”为 32 位值,而实际上根本不扩展。我预计“rsi”的高半部分将无条件归零。但我还没有测试过。 (2认同)
  • @Jorayen:顺便说一句,defuse.ca 上的反汇编程序必须使用 objdump,而不是 GCC(编译器不需要反汇编程序)。它们可能有一个旧的或有缺陷的版本,因为我的 GNU objdump 2.34 在 AT&T 或 Intel 模式下正确反汇编为“esi”。 (2认同)