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

Den*_*aia 80 cpu x86 assembly x86-64 machine-code

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

这个问题的动机

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

我知道这rep是一个前缀,意味着"重复下一个指令cx时间"(或至少它是,在旧的16位x86汇编中).根据这一维基百科汇总表,似乎rep只能与使用movs,stos,cmps,lods,scas(但也许是对新的处理器去掉这个限制).因此,我认为rep nop(没有分号)将重复nop操作cx时间.

然而,经过进一步搜索,我更加困惑.它似乎rep; noppause 映射到完全相同的操作码,并且pause有一些不同的行为nop.2005年的一些旧邮件说不同的东西:

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

有了这些不同的意见,我无法理解正确的含义.

它正在Linux内核中使用(在i386x86_64上)以及此注释:/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */它也在BeRTOS中使用,具有相同的注释.

ugh*_*fhw 68

rep; nop确实与pause指令(操作码F390)相同.它可能用于不支持该pause指令的汇编程序.在以前的处理器上,这根本没有做任何事情,就像nop两个字节一样.在支持超线程的新处理器上,它用作处理器的提示,您正在执行spinloop以提高性能.从英特尔的指令参考:

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

  • 是的,spin-wait循环与busy-wait循环相同.此优点也适用于不支持超线程的CPU.它可以被认为是限制管道中(不必要的)指令的数量(而不是试图并行地进行多次循环迭代) (11认同)
  • @Brendan,哦,现在我明白了!这些现代处理器是[超标量](http://en.wikipedia.org/wiki/Superscalar),因此他们将尝试同时运行多个指令.如果这是一个忙等待循环,那么运行更多指令不会使它更快,因为它只是在等待另一个条件. (11认同)
  • *spin-wait循环*与*[busy-wait loop]相同(http://en.wikipedia.org/wiki/Busy_waiting)*?这种"改进"是否仅适用于超线程处理器?(为什么?) (4认同)

Pet*_*des 12

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

在这种情况下,这意味着您可以rep nop在spinloops中使用而不会破坏向后比较.不知道的旧CPU pause会将其解码为NOP而不会造成任何伤害.在新CPU上,您可以获得节能/ HT友好性的好处,并且当您正在旋转的内存确实发生变化并且您正在离开旋转循环时,可以避免内存排序错误推测.


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

另一种无意义的pause前缀成为新CPU的新指令: lockrep.在不支持该指令的CPU上(在其CPUID中缺少LZCNT功能标志),它解码为f3 xx,运行方式与之相同pause.因此,在旧CPU上,它会产生pause,并且在输入为零时未定义.


一个无意义的pause前缀可能永远不会以不同的方式解码:rep默认情况下由gcc用于定位"通用"CPU(即不针对特定的CPU,lzcnt或者F3 0F BD /r不针对AMD K8或K10.)任何人都需要几十年的时间.可以使CPU解码rep bsr为其他任何东西bsr,因为它存在于大多数Linux发行版的大多数二进制文件中.看看 `rep ret'是什么意思?

  • 英特尔也使用`rep`前缀添加锁省略. (3认同)
  • @ St.Antario:之所以这样说是因为未来的CPU可能会将其识别为某些新指令的一部分。在所有实际的CPU上都是如此,一旦他们使用`f3 xx'建立了编码,便记录了它如何在较旧的CPU上运行。 (2认同)
  • @ St.Antario:有趣!通常,对于较旧的指令,不适用的前缀将被忽略。引入新的说明时,可以选择添加更严格的规则。IDK为什么他们会为此特定情况选择它。 (2认同)