NASM与CMP和OR之间的区别

Eri*_*k W 3 assembly nasm

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

or al, al
Run Code Online (Sandbox Code Playgroud)

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

Zde*_*nek 6

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

如前所述,程序流程由状态寄存器确定,FLAGS在x86(http://en.wikipedia.org/wiki/FLAGS_register)上命名.如您所见,有例如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
Run Code Online (Sandbox Code Playgroud)

代码的功能基于以下任何条件指令.它没有任何意义,因为x |= x它对价值基本没有影响,但对状态寄存器有副作用.

从我们可以阅读的内容中,我们可以使用

or al, al
jnz _someWhere
Run Code Online (Sandbox Code Playgroud)

为了判断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; 这比test一些非常老的x86更快,目前的实现在两种情况下都具有相同的速度.