【问题标题】:What happens when you use a memory override prefix but all the operands are registers?当您使用内存覆盖前缀但所有操作数都是寄存器时会发生什么?
【发布时间】:2018-02-21 14:59:47
【问题描述】:

当您使用内存覆盖前缀但所有操作数都是寄存器时会发生什么?

因此,假设您编码 mov eax, ebxadd eax, ebx,默认为 32 位,但您使用 67h 覆盖。

处理器如何处理这种情况?

【问题讨论】:

  • 66 是操作数大小的前缀,所以它变成了mov ax,bx。您是说67 地址大小前缀吗?
  • 是的,我编辑了原始问题。不,等等,我的意思是最初的问题。这就是重点,将内存前缀与没有内存操作数混合在一起。
  • 66 不是“内存”前缀。 89 d8mov eax, ebx66 89 d8mov ax, bx(在 32 或 64 位模式下,否则 66 前缀使操作数大小为 32 位,而不是默认的 16)。这就是您要问的意思,还是您真的想知道使mov eax, [ebx] 变成mov eax, [bx]67 地址大小前缀。 (或在 64 位模式下,mov eax, [rbx] 变为 mov eax, [ebx]。)
  • 我的意思是 67 小时,我改变了它。谢谢。

标签: assembly memory x86 cpu-architecture overriding


【解决方案1】:

英特尔软件开发人员手册*,第 2 卷,第 2.1 节详细介绍了每个指令前缀的行为。它表示将地址大小前缀 (67h) 与没有内存操作数的指令一起使用是保留的,可能会导致不可预知的行为。

操作数大小前缀 (66h) 可用于在 16 位和 32 位操作数大小之间切换,也可用作某些 SSE2/SSE3/SSSE3/SSE4 指令的强制前缀。其他用途是保留的,可能会导致不可预知的行为。

段覆盖前缀保留在任何分支指令中。

* https://software.intel.com/en-us/articles/intel-sdm

【讨论】:

  • 在真实硬件上,不适用的前缀会被忽略。这就是为什么他们被“保留”而不是“原因#UD”。 lock 除外,#UD 不适用时会这样做。
  • @peter 但英特尔是否记录了“保留”意味着您可以使用它并且会被忽略?我认为这意味着“不要使用它,任何事情都可能发生”。现在似乎在实践中经常忽略保留前缀的使用,这对英特尔来说很方便,因为他们可以在以后使用以前无意义的前缀定义新行为,并在那时记录它在早期芯片上也很好(忽略)。不过,其他保留的行为可能很好 UD。
  • @BeeOnRope:不,我不这么认为,因为他们通常只记录面向未来的保证,而不是当前 CPU 的具体细节,如果他们不想保证未来.正如您所说,他们只会在事后记录忽略行为,例如tzcnt/bsf。但是,有一些情况,例如 rep ret,如果不破坏大量 gcc 编译的二进制文件,就无法重新利用它们,所以 I don't expect any mainstream CPU to repurpose it for decades.
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 2019-05-24
相关资源
最近更新 更多