NEG指令如何影响x86上的标志位?

12

英特尔软件开发手册对neg指令如下描述:

如果源操作数为 0,则 CF 标志位设置为 0;否则设置为 1。OF、SF、ZF、AF 和 PF 标志根据结果设置。

我认为如果将 neg %eax 替换为以下代码,那么 AF 和 CF 应该被设置:

not %eax   # bitwise negation
add $1, %eax

但实际情况并非如此,在真实的CPU上对0x6ffffef5取反会设置AF和CF标志位。


@EvanCarroll:你为什么把这个问题从AT&T语法改成英特尔语法?现在我的答案看起来很奇怪。 - Peter Cordes
@PeterCordes 我不想卷入那场圣战,退出了(回到GAS)。但我认为以[intel]或[x86]标签作为标准化是一个很好的事情。 - Evan Carroll
@EvanCarroll:[Intel]标签与Intel汇编语言语法并没有太多关系。它是普遍指代Intel架构的。但是,对于与Intel或AT&T汇编语言语法相关的问题,存在[intel-syntax]和[att]标签。 - Michael Petch
2
@MichaelPetch:啊,我明白了。对我来说,标签的措辞听起来像是将范围限制在Intel特定的x86扩展(如事务内存)上,而不是一般的x86 ISA问题。(这就是我理解你的评论的方式。我也不确定你是否在说它被限制在那里,还是那只是它所涵盖的一部分,抱歉我有点迂腐)。鉴于已经有了[x86]和[itanium]标签来涵盖这些主题,我认为这是合适的。我认为我们都同意,我们希望将x86问题标记为x86,以便它们可以被找到,而不是散布在[Intel]和[x86]之间。 - Peter Cordes
@PeterCordes:至于你的最后一句话,是的,我们非常赞同。 - Michael Petch
显示剩余2条评论
1个回答

10

neg所有标志位设置为从0执行sub所得到的结果。

此指令序列将所有标志位(包括AF和CF)设置为neg %eax的结果:

xor  %ecx, %ecx
sub  %eax, %ecx     # ecx = 0 - eax

英特尔的文档确实指定了这一点,但不在伪代码操作部分或指令集参考(第2卷)中neg本身的影响标志节中。

关于neg的描述部分的文字包括以下信息:

此操作相当于将操作数从0中减去。

而在第1卷中:

7.3.2.4比较和符号更改指令

[CMP的一个段落]

NEG(否定)指令从零中减去有符号整数操作数。

这篇文章的评论区曾经提出过这些文献的存在,尽管没有直接表述。

有一些证据表明,在英特尔CPU上,neg在内部解码为与sub指令相同的uop。 (例如neg [mem]可以将加载与ALU操作微融合,以及将存储地址和存储数据uop微融合。 inc [mem]只能微融合存储,因此总共需要3个融合域uops)。



有一些证据表明,在英特尔CPU上,neg内部解码为与sub指令相同的uop。有趣的是...这使我最近质疑的行为更加令人惊讶。如果neg在内部被解码为sub,那么neg+add肯定不会比sub更有优势。也许我应该正式报告这个问题。英特尔有问题跟踪器吗? - Cody Gray
@CodyGray:我相信他们以某种形式接受错过优化的错误报告。如果没有公共错误跟踪器,可能会通过论坛帖子进行。除了在godbolt上使用ICC,我没有使用过它。 - Peter Cordes
@tbodt:结果发现它确实有文档记录,只是你没有找对地方。> . < - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接