2016-09-18 119 views
7

“test eax,eax”比“cmp eax,0”更有效吗?在“cmp eax,0”不符合要求的情况下,是否有必要使用“test eax,eax”?Linux程序集:“test eax,eax”和“cmp eax,0”有什么区别

谢谢!

+2

'test'比'cmp'短,因为它不包含immediate。 –

+0

在您提供的示例中,与OpCode计数观点没有什么不同。你只是问“EAX是否为零?”所以它可能只是整个代码中的一致性问题。参考英特尔体系结构和说明http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html –

+2

Peter Cordes在这里有一个很好的答案:http:// stackoverflow。 com/a/33724806/3857942,它涉及'cmp'和'test'之间的区别。这个问题本身并不重复,因为问题是关于使用'或'进行测试的问题,但答案肯定与这个问题有关。 –

回答

8

由于臧明杰已经在评论已经说了,test eax,eax几乎是相同的cmp eax,0,但它短于cmp,因为cmp你必须提供0作为参数。请注意,节省不是很大,因为第二个操作数得到符号扩展以匹配第一个操作数的大小,所以它不一定需要整个4个字节来表示该零。

现在,你问的是是否有任何其他差异。这是一个合理的问题,因为cmp是算术运算(它执行减法并丢弃结果),而test是逻辑运算(它执行按位AND并放弃结果),因此可以合理怀疑他们可能会不同地修改Flags寄存器。

事实证明,这两个指令修改Flags寄存器在几乎相同的方式。两条指令都修改标志寄存器的OF SF ZF AF PF和CF位。 test指令总是清除OF和CF,但这也是cmp对零的做法。唯一的区别是cmp指令将正确设置the obscure AF flag,而test指令将使该标志的内容不确定。但在cmp eax,0的情况下,无论eax的值如何,AF将始终被清除,因此您从test eax,eax中不能从cmp eax,0中学到任何东西。

因此,我会得出结论,test eax,eax会给你cmp eax,0不会的东西,反之亦然。除了保存一个或两个指令代码之外,这两条指令似乎对于任何实际的或甚至不太实际的目的都是完全可以互换的。

使用test eax,eax而不是cmp eax,0表明您知道您的装配。它还表明,你更喜欢稍微隐蔽的,稍微好一点的表现指令,而不是简单易懂的指令。这是一种倾向于从其他极客获得奖励积分的东西,但在过去的几十年中,它在现实世界中没有任何实际用处。

+1

英特尔Core2或Nehalem可能会有性能差异,其中TEST可以与CMP的更多JCC类型进行宏观融合。例如Core2和Nehalem可以将'test eax,eax/js'宏观融合,但不能'cmp eax,0/js'。不过,Nehalem可以将'cmp eax,0/jl'宏观融合。 (Core2不能,但是Core2只能在32位模式下完全熔合)。 [见Agner Fog's microarch pdf](http://agner.org/optimize/) –

相关问题