首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在x86程序集中"rep;nop;“是什么意思?它和“暂停”指令一样吗?

在x86程序集中"rep;nop;“是什么意思?它和“暂停”指令一样吗?
EN

Stack Overflow用户
提问于 2011-08-16 23:12:25
回答 2查看 28.6K关注 0票数 94
  • rep; nop是什么意思?
  • 它和pause指令一样吗?
  • 它和rep nop (没有分号)一样吗?
  • 简单的nop指令有什么区别?
  • 它在AMD和Intel处理器上的表现是否不同?
  • (奖金)这些指示的正式文件在哪里?

这个问题的动机

另一个问题的评论中进行了一些讨论之后,我意识到我不知道rep; nop;在x86 (或x86-64)程序集中意味着什么。而且我在网上找不到一个很好的解释。

我知道rep是一个前缀,意思是“重复下一个指令cx时间”(或者至少在旧的16位x86程序集中是这样)。根据这个维基百科汇总表rep似乎只能与movsstoscmpslodsscas一起使用(但在较新的处理器上可能消除了这个限制)。因此,我认为rep nop (没有分号)会重复nop操作cx次数。

然而,经过进一步的搜索,我更加困惑了。rep; noppause 映射到完全相同的操作码以及pause似乎有着与nop不同的行为。一些2005年的旧邮件说了不同的话:

  • “尽量不要烧太多的电”
  • “它相当于”nop“,仅用2字节编码即可。”
  • “这是英特尔的魔力,就像'nop,但让其他HT兄弟一起跑‘”
  • “这是英特尔的停顿和雅典兰的快速填充”

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-08-16 23:22:37

rep; nop确实与pause指令(操作码F390)相同。它可能用于不支持pause指令的汇编程序。在以前的处理器上,这只是不起任何作用,就像nop一样,只是用了两个字节。在支持超线程的新处理器上,它被用作对处理器的提示,提示您正在执行一个spinloop以提高性能。来自英特尔指令参考

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

票数 83
EN

Stack Overflow用户

发布于 2015-11-10 20:46:44

rep nop = F3 90 = pause的编码,以及它如何在不支持pause的旧CPU上解码。

lock**)前缀(不适用于指令的除外)实际上被现有CPU忽略。

文档称,使用不适用于is 的指令的将“保留并可能导致不可预测的行为”,因为未来的CPU可能会将其识别为某些新指令的一部分。一旦使用f3 xx建立任何特定的新指令编码,就会记录其在旧CPU上的运行方式。(是的,x86的操作码空间是如此的有限,以至于他们会做这种疯狂的事情,而且是的,这会使解码器变得复杂。)

在本例中,pause意味着您可以在自旋循环中使用,而无需向后中断compat。不知道pause的旧CPU会将其解码为NOP,不会造成任何伤害,英特尔的ISA ref手册pause保证了这一点。在新的CPU上,您可以获得节能/ HT友好性的好处,而当您正在运行的内存发生变化时,避免记忆有序的错误推测就会发生变化,而您将留下自旋循环。

链接到英特尔的手册和大量其他x86标签wiki信息页面上的好东西

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

但是tzcntbsf对非零输入做同样的事情,所以编译器可以也确实使用tzcnt,即使不能保证目标CPU以tzcnt的形式运行。AMD有快速的tzcnt,慢的bsf,而在英特尔,它们都是快速的。只要正确性不重要(您不依赖于标记设置,或者在input=0情况下不依赖于目标未修改的行为),在支持它的CPU上让它解码为tzcnt是有帮助的。

一种无意义的rep前缀可能永远不会有不同的解码方式: gcc在针对“通用”CPU时默认使用rep ret (即不使用-march-mtune来访问特定的CPU,也不使用K8或K10)。再过几十年,任何人都可以将rep ret解码为ret以外的任何东西,因为它存在于大多数Linux发行版的大多数二进制文件中。请参阅卑劣?

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7086220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档