2016-11-15 72 views
3

在一次采访中,有人问我是否知道x64指令的行为因所用CPU而异,我找不到任何地方的任何文档,是否有人知道这些指令是什么以及为什么是这种情况?在不同CPU上表现不同的X64指令

+1

@PeterCordes的这个问题的答案在很大程度上取决于 “指令” 和 “CPU” 的精确定义。例如,'cpuid'是一个死牌,但在P4上它有争议地暴露了序列号。 –

+2

目前还没有很多公司可以烘焙x86和x64处理器芯片,AMD和Intel是唯一真正的幸存者。 x64是由AMD发明的,后来被英特尔采用。他们并不总是同意如何扩展架构,3DNow和MMX都相当死板。从他们的错误中吸取教训,他们确实在用户代码中一起行动。但是保护模式和虚拟化,操作系统关心的东西仍然完全不同。是的,你可以很容易地回答cpuid :) –

+0

MMX是我认为x86-64所需的基准部分,因为x86-64需要SSE和SSE2,并且一些SSE指令在MMX寄存器上运行。所以我们可以预计CPU将永远支持它,但即使在Skylake上,某些指令的MMX版本的吞吐量也会低于其XMM等价物。 MMX在未来CPU中的支持可能会变得更加残缺,并且会被微码化或者其他。 (与3DNow相比,3DNow已经死掉,大多数CPU完全不支持,甚至包括AMD的新CPU)。 –

回答

5

还有一些,即leave a register or some flags with undefined values。英特尔和AMD在那里可能有所不同

在某些情况下,对于这些未定义的情况,实际硬件的实际行为会保留对依赖于它的某些旧软件的向后兼容性。例如,根据英特尔的手册,输入= 0时的BSF会设置ZF并使目标寄存器中的内容未定义。但是,在这种情况下,AMD的手册(以及真正的英特尔+ AMD硬件)在没有修改的情况下仍然保留目的地。 (这就是为什么bsf/具有输出依赖性的原因。)

如果性能差异计数很多(请参阅标记wiki中的链接)!


你不只是在谈论不受支持的说明,是吗?像一些非常早期的x86-64 CPU在长时间模式下不支持LAHF/SAHF?或者KX早期也不支持CMPXCHG16B。

不受支持的指令最有趣的情况是LZCNT在不支持它的CPU上解码为REP BSR。即使对于非零输入,它们也会返回相反的结果。 (_tzcnt_u32(x) == 31-bsr(x))。在不支持它的CPU上,TZCNT与REP BSF类似地解码,但除了输入= 0之外,它们执行相同的操作。我之前没有提及过,因为运行相同机器码的与之不一样运行相同的指令不同,但它听起来像这是你要求的东西。

我们是否只谈论非特权指令?特权指令的行为可能存在更多差异。例如,Intel和AMD在SYSRET中都有不同的错误,以避免恶意用户空间导致内核挂起。


另一种情况下我不知道计数:PREFETCHW Intel CPU的距离至少以酷睿2的Haswell作为NOP运行,但在AMD的CPU(英特尔自Broadwell微架构)as an actual prefetch

因此,有些CPU会将其作为NOP运行,有些将其作为预取运行(因此无论哪种方式均无法在架构上显示效果),除非在古代CPU中作为非法insn进行故障。 64位Windows8.1 apparently requires that PREFETCHW can run without faulting(它阻止它在(某些?)64位Pentium4 CPU上运行)。

+2

除了明显的'cpuid',你可以在'tzcnt'中执行'rep bsf'和'lzcnt'作为CPU上的'rep bsr'

+0

我认为这是他所说的那种指令,我们正在讨论DRM,只有在特定的CPU模型上运行某种方式的代码才是防止共享解压缩的二进制文件的一种方法。 – awpsoleet

+1

关于'bsf' /'bsr',AMD似乎实际上记录了如果输入为零,即与实际的英特尔行为一致,则寄存器不变。至少根据[本源](https://chessprogramming.wikispaces.com/BitScan#Processor%20Instructions%20for%20Bitscans-x86-Bsf/Bsr%20behavior%20with%20zero%20source)。 – BeeOnRope

3

有很多的英特尔和AMD

  • 英特尔64的BSFBSR指示行事不同于AMD64的当源是零并且操作数长度为32位之间的差异。处理器设置零标志并保留目标的高32位未定义。
  • Intel 64缺少一些被认为是AMD64体系结构的MSR。这些包括SYSCFGTOP_MEMTOP_MEM2
  • 英特尔64允许SYSCALL/SYSRET仅在64位模式下(未在兼容模式),[33],并允许在两种模式SYSENTER/SYSEXIT。[34]在长模式的两种子模式中,AMD64缺少SYSENTER/SYSEXIT
  • 在64位模式下,具有66H(操作数大小覆盖)前缀的分支附近行为有所不同。英特尔64忽略此前缀:该指令具有32位符号扩展偏移量,并且指令指针不被截断。 AMD64在指令中使用16位偏移量字段,并清除指令指针的前48位。
  • AMD处理器提高浮点数当执行80位信令NaN的FLDFSTP时,无效异常,而英特尔处理器不执行此操作。
  • 当使用SYSRET返回到非规范地址时,AMD64处理器在特权级别3执行通用保护错误处理程序,而在Intel 64处理器上,它在特权级别0执行。[38] [39]

https://en.wikipedia.org/wiki/X86-64#Differences_between_AMD64_and_Intel_64

相关问题