当使用“或”而不是"cmp“时,是否有一个主要的积极品质?
请考虑这个函数序言:
push ebp
mov ebp,esp
push ebx
xor eax,eax ;error return code
mov ecx,[ebp +8] ;first integer arg after return addr.
mov edx,[ebp +12] ;second integer argument该函数应计算a / b或a % b。
首先,我需要检查0除数。
我的直觉就是组装
cmp edx,0
je InvalidDivisor但是,当我查看有关汇编程序的高级书籍时,会用到以下内容:
or edx,edx
jz InvalidDivisor 我的问题是,为什么第二个解决方案“更正确”?
计算或操作和检查零标志不需要比比较两个值更长的时间吗?
这仅仅是一个更高级的编码风格的问题吗?
发布于 2017-03-20 17:58:41
or edx,edx是两个字节,cmp edx, 0是三个,所以如果您关心大小,就知道应该选择哪一个。
如果你更关心速度,那么你实际上需要测量。Or显然会“更改”寄存器,如果下一条指令使用相同的寄存器,则可能会增加延迟。
83 fa 00 cmp edx,0x0
09 d2 or edx,edx ; Smaller
85 d2 test edx,edx ; Smaller and better, updates ZF but does not store the result发布于 2017-03-20 17:55:28
这两种指令汇编成:
83 fa 00 cmp edx,0x0
09 d2 or edx,edx正如您所看到的,使用or更短(所以在运行时加载的代码更少),并且具有相同的效果。然而,实际上更好的做法是:
85 d2 test edx,edx 它还设置了零标志,如果edx是零,并且进一步的操作知道他们不需要依赖结果,即使CPU还没有弄清楚这一点。
发布于 2017-03-21 12:23:48
问题中的例子是Intel x86,而CMP和OR指令也存在于其他处理器中。
在MOS 6502上,没有那么多寄存器,您也可以在状态标志中传递参数或返回值,您可以避免使用影响C标志的指令。因此,与CMP相比,您可以更喜欢EOR (独占或)和,OR。在6502上,几乎所有复制数据的指令都会影响N和Z标志。
在Atmel 8位AVR微控制器系列上,有一个方便的指令CPSE (比较和跳过如果相等),它不影响任何标志,如果我记得正确的话。AVR-GCC将32个寄存器中的一个指定为“零寄存器”,然后发射代码与该寄存器一起使用CPSE。
https://stackoverflow.com/questions/42910429
复制相似问题