-
rep; nop
是什么意思? -
与
pause
指令相同吗? -
是否与
rep nop
相同(没有分号)? -
简单的
nop
指令有什么区别? -
在AMD和英特尔处理器上它的表现是否不同?
-
(奖金)这些说明的官方文件在哪里?
这个问题的动机
在another question的评论中进行了一些讨论后,我意识到我不知道 rep; nop;
在x86(或x86-64)程序集中的含义 . 而且我也无法在网上找到一个好的解释 .
我知道 rep
是一个前缀,意思是“重复下一条指令 cx
次”(或者至少它是旧的16位x86程序集) . 根据summary table at Wikipedia,似乎 rep
只能与 movs
, stos
, cmps
, lods
, scas
一起使用(但可能在新处理器上删除了此限制) . 因此,我认为 rep nop
(没有分号)会重复 nop
次 cx
次 .
然而,经过进一步搜索,我更加困惑 . 似乎 rep; nop
和 pause
map to the exactly same opcode, pause
的行为与 nop
有点不同 . 有些old mail from 2005说不同的东西:
-
"try not to burn too much power"
-
"it is equivalent to 'nop' just with 2 byte encoding."
-
"it is magic on intel. Its like 'nop but let the other HT sibling run'"
-
"it is pause on intel and fast padding on Athlon"
有了这些不同的意见,我无法理解正确的含义 .
它正在Linux内核中使用(在i386和x86_64上)以及此注释: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
它也是being used in BeRTOS,具有相同的注释 .
2 回答
rep; nop
确实与pause
指令(操作码F390
)相同 . 它可能用于不支持pause
指令的汇编程序 . 在以前的处理器上,这根本没有做任何事情,就像nop
一样,只有两个字节 . 在支持超线程的新处理器上,它用作处理器的提示,您正在执行spinloop以提高性能 . 来自Intel's instruction reference:不适用于指令的前缀将被忽略 . 但是,未来的CPU可以使用该字节序列来编码新指令 . (是的,x86操作码空间非常有限,以至于他们做了这样的疯狂的事情,是的,这使得解码器变得复杂 . )
在这种情况下, it means you can use pause in spinloops without breaking backwards compat . 不知道
pause
的旧CPU会将其解码为NOP而不会造成任何伤害 . 在新的CPU上,你可以获得省电/ HT友好的好处,以及avoiding memory-ordering mis-speculation当你的内存离开旋转循环时 .在x86标签维基信息页面链接到英特尔的手册和大量其他好东西:https://stackoverflow.com/tags/x86/info
另一种无意义的
rep
前缀成为新CPU的新指令:lzcnt
是F3 0F BD /r
. 在不支持该指令的CPU上(在其CPUID中缺少LZCNT功能标志),它将解码为rep bsr
,其运行方式与bsr
相同 . 因此在旧CPU上,它会产生32 - expected_result
,并且在输入为零时未定义 .一个无意义的
rep
前缀的情况可能永远不会以不同的方式解码:rep ret
默认情况下由gcc用于定位"generic" CPU(即不针对具有-march
或-mtune
的特定CPU,而不是针对AMD K8或K10 . )这将是几十年之前任何人都可以制作一个将rep ret
解码为ret
以外的其他CPU,因为它存在于大多数Linux发行版的大多数二进制文件中 . 见What doesrep ret
mean?