在x86中,"test eax,eax"和"cmp eax,0"有什么区别

  • 本文关键字:eax 区别 cmp x86 test assembly x86
  • 更新时间 :
  • 英文 :


test eax, eax是否比cmp eax, 0更有效率?在cmp eax, 0不符合要求的情况下,是否需要test eax, eax ?

正如臧明杰在评论中已经说过的,test eax, eax几乎与cmp eax, 0相同,除了它比cmp短,因为对于cmp,你必须提供0作为参数。注意,节省的空间并不是很大,因为第二个操作数进行了符号扩展,以匹配第一个操作数的大小,所以不一定需要整整4个字节来表示这个0。

现在,你要问的是是否还有其他的区别。这是一个合理的问题,因为cmp是一个算术运算(它执行减法并丢弃结果),而test是一个逻辑运算(它执行按位与运算并丢弃结果),所以人们可以合理地怀疑它们可能以不同的方式修改Flags寄存器。

结果是,两个指令以几乎相同的方式修改Flags寄存器。两个指令都修改标志寄存器的OF、SF、ZF、AF、PF和CF位。test指令总是清除OF和CF,但这也是cmp对0所做的。唯一的另一个区别是cmp指令将正确设置模糊的AF标志,而test指令使该标志的内容未定义。但是在cmp eax,0的情况下,无论eax的值是多少,AF都会被清除,所以你可以从cmp eax, 0中学到的东西,你不能从test eax, eax中学到。

因此,我可以得出结论,没有test eax, eax会给你cmp eax, 0不会给你的东西的情况,反之亦然。除了节省一两个字节的指令代码外,这两条指令似乎完全可以互换用于任何实际目的,甚至不太实际的目的。

使用test eax, eax而不是cmp eax, 0表明您了解您的汇编。它还表明,与直接易懂的指令相比,您更喜欢略显晦涩但性能稍好一些的指令。这是一种倾向于从其他极客那里获得加分的东西,但在过去几十年左右的时间里,它在现实世界中没有任何实际用途。

# 的区别(理论)

正如上面在评论和接受的回答中所述,当以这种方式使用时,这些指令几乎相同,但是如果它们是相同的,为什么指令集中有两个指令呢?

因为它们用于不同的操作数是不同的。事实上,test same,same作为0的比较,只是2的补码和FLAGS如何工作的一个方便的结果,使其成为一个有用的窥视孔优化。

TEST指令在arg0和arg1的位对上使用AND逻辑,并且可以检查特定位是否设置,然后相应地设置FLAGS。(整数结果被丢弃)。就像cmp从减法中设置FLAGS,同时丢弃整数结果。

# 操作(测试)

HTML除了来自Intel的vol.2 PDF手册

TEMP ← SRC1 **AND** SRC2;
SF ← MSB(TEMP);
IF TEMP=0
    THEN ZF ← 1;
    ELSE ZF ← 0;
FI:
PF ← BitwiseXNOR(TEMP[0:7]);
CF ← 0;
OF ← 0;
(* AF is undefined *)

标记影响

OF和CF标志设置为0。设置SF、ZF和PF标志根据结果(参见上面的"操作"部分)。的AF标志的状态未定义

(TEST操作将标志CF和OF设置为零。SF被设置为AND运算结果的最高有效位。如果结果为0,则ZF设置为1,否则设置为0。


虽然CMP指令使用SUB指令并从arg0中减去arg1,并将根据给定的args设置CF(进位标志)和ZF(零标志)到CMP指令,如果两者相等(arg1==arg0),那么很明显结果将为零,ZF将被设置为1,如果arg0>arg1则不设置任何标志(对于ZF和CF保持0),如果arg0 <arg1则ZF将保持0,因为它们不相等,但CF将被设置。>

# 操作(CMP)

temp ← SRC1 − SignExtend(SRC2); 
ModifyStatusFlags; 
   (* Modify status flags in  the same manner as the SUB instruction*)

标记影响

根据结果设置CF、OF、SF、ZF、AF和PF标志。

最新更新