什么是“代表; nop;”在x86汇编中意味着什么?它与“暂停”指令相同吗?

时间:2011-08-16 23:12:25

标签: assembly x86 cpu x86-64

  • rep; nop是什么意思?
  • 是否与pause指令相同?
  • 是否与rep nop相同(没有分号)?
  • 简单的nop指令有什么区别?
  • 在AMD和英特尔处理器上的表现是否不同?
  • (奖金)这些说明的官方文件在哪里?

此问题的动机

another question的评论中进行了一些讨论之后,我意识到我不知道x {(或x86-64)汇编中rep; nop;的含义。而且我也无法在网上找到一个好的解释。

我知道rep是一个前缀,意味着“重复下一条指令cx次”(或者至少它是旧的16位x86程序集中) 。根据此summary table at Wikipedia,似乎rep只能与movsstoscmpslodsscas一起使用(但可能在新处理器上删除了此限制)。因此,我认为rep nop(没有分号)会重复nop次操作cx次。

然而,经过进一步搜索,我更加困惑。似乎rep; noppause map to the exactly same opcodepause的行为与nop的行为略有不同。有些old mail from 2005说了不同的话:

  • “尽量不要燃烧太多力量”
  • “它只相当于'nop',仅使用2字节编码。”
  • “它对英特尔来说是神奇的。它就像'nop但是让其他HT兄弟跑了'”
  • “在英特尔停顿并在Athlon上快速填充”

有了这些不同的意见,我无法理解正确的意思。

它在Linux内核中使用(在i386x86_64上)以及此评论:/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */它也是being used in BeRTOS,具有相同的注释。< / p>

2 个答案:

答案 0 :(得分:66)

rep; nop确实与pause指令(操作码F390)相同。它可能用于尚不支持pause指令的汇编程序。在以前的处理器上,这根本没有做任何事情,就像nop一样,只有两个字节。在支持超线程的新处理器上,它用作处理器的提示,您正在执行spinloop以提高性能。来自Intel's instruction reference

  

改善了自旋等待循环的性能。当执行“自旋等待循环”时,Pentium 4或Intel Xeon处理器在退出循环时会遭受严重的性能损失,因为它检测到可能的内存顺序违规。 PAUSE指令向处理器提供代码序列为自旋等待循环的提示。在大多数情况下,处理器使用此提示来避免内存顺序违规,从而大大提高了处理器性能。因此,建议在所有自旋等待循环中放置PAUSE指令。

答案 1 :(得分:8)

忽略不适用于指令的前缀。但是,未来的CPU可以使用该字节序列来编码新指令。 (是的,x86操作码空间是如此有限,以至于他们做了这样的疯狂的事情,是的,这使得解码器变得复杂。)

在这种情况下,表示您可以在spinloops中使用pause而不会向后突破compat 。不知道pause的旧CPU会将其解码为NOP而不会造成任何伤害。在新CPU上,您可以获得省电/ HT友好性的好处,并且当您正在旋转的内存确实发生变化并且您正在离开旋转循环时,avoiding memory-ordering mis-speculation

在x86标签维基信息页面上链接到英特尔手册和大量其他好东西:https://stackoverflow.com/tags/x86/info

另一个无意义rep前缀成为新CPU指令的情况:lzcntF3 0F BD /r。在不支持该指令的CPU上(在其CPUID中缺少LZCNT功能标志),它将解码为rep bsr,其运行方式与bsr相同。因此,在旧CPU上,它会生成32 - expected_result,并且在输入为零时未定义。

一个无意义的rep前缀可能永远不会以不同的方式解码:rep ret默认情况下由gcc用于定位“通用”CPU(即不使用{{1}定位特定CPU }或-march,而不是针对AMD K8或K10。)几十年前,任何人都可以制作一个将-mtune解码为除rep ret以外的任何内容的CPU,因为它存在于大多数二进制文件中在大多数Linux发行版中。见What does `rep ret` mean?