Assembly 避免使用条件分支
现代处理器使用了非常尖端的技术来尽可能快地执行代码。一个普遍技术称为预测执行。这种技术使用CPU的并行处理能力来同时执行多条指令。条件分支与这项技术有冲突。一般说来,处理器是不知道分支是否会执行。如果执行了,跟没有执行相比执行的是一组不同的指令。处理器试着预测分支是否执行。如果预测错误,处理器就浪费了它的时间去执行了一些错误的代码。
个分支。
SETxx 指令提供了在一定情况下替换分支的方法。基于FLAGS寄存器的状态,这些指令将一个字节的寄存器或内存空间中的值置为0或1。在SET后的字符与条件分支使用的是一样的。如果SETxx 条件为真,那么储存的结果就为1,如果为假,则储存的结果就为0。例如:
使用这些指令,你可以开发出一些进行数值运算的精巧的技术,而不需要使用分支。
例如,考虑查找两个数的最大数的问题。这个问题的标准解决方法是使用一条CMP指令再使用条件分支对最大值进行操作。下面这个例子展示了不使用分支如何找到最大值。
这个诀窍是产生一个可以用来选择出正确的最大值的俺码。在30行的SETG指令如果第二个输入值是最大值就将BL置为1,否则就置为0。这
不是真正需要的掩码。为了得到真正需要的掩码,31行对整个EBX寄存器使用了NEG指令。(注意:EBX在前面已经置为0了。)如果EBX等于0,那
么这条指令就不做任何事情;但是如果EBX为1,结果就是-1的补码表示或0xFFFFFFFF。这正好是需要的位掩码。剩下的代码就是使用这个位掩
码来选择出正确的输入的最大值。
另外一个可供选择的诀窍是使用DEC语句。在上面的代码中,如果用DEC代替NEG,那么结果同样会是0或0xFFFFFFFF。但是,与使用NEG相比,得到值将是反过来的。