是test eax, eax
不是更有效cmp eax, 0
?是否有test eax, eax
必要在cmp eax, 0
不满足要求的地方?
Mik*_*kis 29
正如臧明杰在评论中已经说过的那样,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
指令将正确设置隐藏AF
标志,而指令则保留该标志test
的内容未定义.但是在cmp eax,0
AF 的情况下总是会被清除,无论其价值如何eax
,所以没有什么可以从cmp eax,0
你不会从中学到的东西中学到test eax,eax
.
因此,我的结论是,没有任何情况test eax,eax
会给你一些cmp eax,0
不会,反之亦然的东西.除了保存一个或两个指令代码之外,这两条指令似乎完全可以互换用于任何实际或甚至不那么实用的目的.
使用test eax,eax
而不是cmp eax,0
显示你知道你的装配.它还表明,您更倾向于使用一种稍微含糊不清且性能稍好的指令而不是直接易懂的指令.这种东西往往会从其他极客那里获得奖励积分,但在过去的几十年里,它在现实世界中没有任何实际用处.
#差异(理论)
正如上面在评论和接受的答案中所述,这些说明几乎相同当以这种方式使用时,但是如果指令集中有两条指令,为什么它们呢?
因为如果与不同的操作数一起使用它们是不同的。test same,same
与零进行比较
的事实只是 2 的补码和 FLAGS 如何工作的一个方便的结果,使其成为有用的窥视孔优化。
TEST 指令对来自 arg0 和 arg1 的位对使用 AND 逻辑,可以检查是否设置了特定位,然后相应地设置 FLAGS。(丢弃整数结果)。就像cmp
从减法中设置 FLAGS 而丢弃整数结果一样。
Run Code Online (Sandbox Code Playgroud)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 将被设置。
Run Code Online (Sandbox Code Playgroud)temp ? SRC1 ? SignExtend(SRC2); ModifyStatusFlags; (* Modify status flags in the same manner as the SUB instruction*)
受影响的标志
根据结果设置 CF、OF、SF、ZF、AF 和 PF 标志。