英特尔软件开发手册对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标志位。
英特尔软件开发手册对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标志位。
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)。