NASM与CMP和OR之间的差异

时间:2015-02-13 20:16:03

标签: assembly nasm

我有2个问题。第一个:'或'与'cmp'有什么区别?我已经看过了两个,看起来他们做了同样的事情。我的第二个问题:什么是

or al, al

意思?它不应该一直返回真(如x == x)吗?

1 个答案:

答案 0 :(得分:6)

实际上,汇编并不像return true那样简单。一般来说,条件执行通常基于状态寄存器。我将在此解释中使用Intel x86架构。请注意,其他架构是不同的,但基本原则保持不变。

如前所述,程序流程由状态寄存器确定,在x86(http://en.wikipedia.org/wiki/FLAGS_register)上名为FLAGS。如您所见,有ZF(零标志)位。如果执行jzjnz等条件指令,则会检查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

为什么这样?正如您从提供的链接中看到的那样,cmpor在操作上略有不同。 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更快,当前的实现在两种情况下都具有相同的速度。