我有2个问题。第一个:'或'与'cmp'有什么区别?我已经看过了两个,看起来他们做了同样的事情。我的第二个问题:什么是
or al, al
意思?它不应该一直返回真(如x == x)吗?
答案 0 :(得分:6)
实际上,汇编并不像return true
那样简单。一般来说,条件执行通常基于状态寄存器。我将在此解释中使用Intel x86架构。请注意,其他架构是不同的,但基本原则保持不变。
如前所述,程序流程由状态寄存器确定,在x86(http://en.wikipedia.org/wiki/FLAGS_register)上名为FLAGS
。如您所见,有ZF
(零标志)位。如果执行jz
或jnz
等条件指令,则会检查ZF
并根据此状态执行(或不执行)跳转。
FLAGS
寄存器在执行代码时更新,每条指令将一些(有时没有)位设置为适当的值。可以在给定体系结构的适当手册中读取此数据。例如,在x86上,add
指令改变CF
(进位标志)。
如果你查找or
指令,它会像这样更新FLAGS
:" OF和CF标志被清除;根据结果设置SF,ZF和PF标志。" (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf#G5.251049)。
cmp
指令更新FLAGS
,如下所示:"根据结果设置CF,OF,SF,ZF,AF和PF标志。" (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf#G4.22557)
从中得出
or al, al
代码的功能基于以下任何条件指令。没有任何意义,因为x |= x
基本上没有对价值产生影响,但对状态寄存器有副作用。
从我们可以阅读的内容中,我们可以使用
or al, al
jnz _someWhere
为了确定al
寄存器的内容是否为非零,如果是,请跳转到_someWhere
。
为什么这样?正如您从提供的链接中看到的那样,cmp
和or
在操作上略有不同。 cmp
是隐藏的减法,而or
直接映射到CPU硬件。减法是通过加法单元(否定和加法)完成的,或者是通过一个简单的或门完成的,它更快。在执行速度方面,这会产生轻微的差异(如果有的话)。
如果我们考虑使用现代x86处理器,我不认为这种优化(或根本不需要使用程序集)应该完成,除非你是这方面的真正专家并且我认为这个星球上的人很少。
TL; DR:
or al, al
- 允许在不更改al
的值的情况下进行符号和零比较
cmp al, x
- 允许与x进行比较而不更改al
的值
test al, x
- 允许在后台使用and
指令进行较小/较大和相等的检查,不会修改al
and al, x
- 与test al, x
相同,但会修改al
;在一些非常老的x86上,这比test
更快,当前的实现在两种情况下都具有相同的速度。