【问题标题】:x86-64 duplicate instruction prefixx86-64 重复指令前缀
【发布时间】:2015-06-05 10:12:24
【问题描述】:

操作码前缀可以重复。例如,让我们以 8B 操作码(mov)和操作数大小覆盖前缀:

66 66 66 66 66 8B 00

visual studio 反汇编器的输出(x64 模式):

mov ax, word ptr [rax]

现在,让我们来看看这个:

66 66 66 66 67 8B 00

visual studio 反汇编器的输出:

mov ax, word ptr [eax]

还有这个:

66 66 66 67 /*it throws away left side*/ 67 8B 00

visual studio 反汇编器的输出:

??
??
??
??
mov eax, dword ptr [eax]

所以,我想问一下为什么前缀 67 不能重复。是 Visual Studio 特定的处理与硬件语义不匹配还是 cpu 本身不允许这样做?

【问题讨论】:

  • 复制前缀是未定义的行为。也就是说,我不知道为什么 VS 反汇编会这样做。例如,ndisasmobjdump 按预期解码。
  • "You could only form an infinitely long instruction by using redundant prefixes in front on the opcodes"。 "例如,您可以将看似无害的指令:89 E5 mov %sp,%bp 变成一个非常长的指令:66 66 66 66 … 66 66 89 E5 mov %sp,%bp"
  • @LưuVĩnhPhúc 你不能有无限的前缀。虽然我不相信重复的“经典”前缀会导致未定义的行为,但 gas 将它们用于长 NOP,总指令长度大于 15。

标签: assembly cpu disassembly


【解决方案1】:

似乎 VS 根本不支持这一点。使用 ndisasm(nasm 的反汇编程序),它运行良好,它被反汇编为:

6767668B00        mov ax,[eax]

但问题在于,在正常的 64 位环境中,仅使用低 32 位寻址通常是不可能的。

但我测试过:

 67674889D8        mov rax,rbx

并且 CPU (i7-4770) 毫无例外地执行了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多