使用 CMP reg,0 与 OR reg,reg 测试寄存器是否为零? [英] Test whether a register is zero with CMP reg,0 vs OR reg,reg?

查看:31
本文介绍了使用 CMP reg,0 与 OR reg,reg 测试寄存器是否为零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码是否有任何执行速度差异:

Is there any execution speed difference using the following code:

cmp al, 0
je done

以及以下内容:

or al, al
jz done

我知道 JE 和 JZ 指令是相同的,而且使用 OR 可以将大小改进一个字节.但是,我也关心代码速度.似乎逻辑运算符会比 SUB 或 CMP 快,但我只是想确定一下.这可能是大小和速度之间的权衡,也可能是双赢(当然代码会更不透明).

I know that the JE and JZ instructions are the same, and also that using OR gives a size improvement of one byte. However, I am also concerned with code speed. It seems that logical operators will be faster than a SUB or a CMP, but I just wanted to make sure. This might be a trade-off between size and speed, or a win-win (of course the code will be more opaque).

推荐答案

这取决于确切的代码序列、具体的 CPU 以及其他因素.

It depends on the exact code sequence, which specific CPU it is, and other factors.

或al, al,的主要问题在于它修改"了EAX,这意味着使用EAX的后续指令以某种方式可能会停止,直到该指令完成.请注意,条件分支 (jz) 也取决于指令,但 CPU 制造商做了大量工作(分支预测和推测执行)来缓解这种情况.另请注意,理论上 CPU 制造商有可能设计出识别 EAX 的 CPU 在这种特定情况下不会改变,但是有数百种这种特殊情况以及识别大多数情况的好处其中太少了.

The main problem with or al, al, is that it "modifies" EAX, which means that a subsequent instruction that uses EAX in some way may stall until this instruction completes. Note that the conditional branch (jz) also depends on the instruction, but CPU manufacturers do a lot of work (branch prediction and speculative execution) to mitigate that. Also note that in theory it would be possible for a CPU manufacturer to design a CPU that recognises EAX isn't changed in this specific case, but there are hundreds of these special cases and the benefits of recognising most of them are too little.

cmp al,0 的主要问题是它稍大,这可能意味着指令获取速度较慢/缓存压力更大,并且(如果是循环)可能意味着代码不再适合某些 CPU 的循环缓冲区".

The main problem with cmp al,0 is that it's slightly larger, which might mean slower instruction fetch/more cache pressure, and (if it is a loop) might mean that the code no longer fits in some CPU's "loop buffer".

正如 Jester 在评论中指出的那样;test al,al 避免了这两个问题 - 它小于 cmp al,0 并且不修改 EAX.

As Jester pointed out in comments; test al,al avoids both problems - it's smaller than cmp al,0 and doesn't modify EAX.

当然(取决于特定的序列)AL 中的值一定来自某个地方,如果它来自适当设置标志的指令,则可以将代码修改为避免使用另一条指令稍后再次设置标志.

Of course (depending on the specific sequence) the value in AL must've come from somewhere, and if it came from an instruction that set flags appropriately it might be possible to modify the code to avoid using another instruction to set flags again later.

这篇关于使用 CMP reg,0 与 OR reg,reg 测试寄存器是否为零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆