现代处理器使用了非常尖端的技术来尽可能快的执行代码。一个普遍的技术称为预测执行。这种技术使CPU的并行处理能力来同时执行多条指令。条件分支与这项技术有冲突。一般来说,处理器是不知道分支是否会执行。
一个避免这个问题的方法就是如果可能尽量避免使用条件分支。在计算eax中比特位为1的例子中,一般会用一个分支跳转到INC指令(检查CF标志),下面展示了如何使用ADC指令直接加上进位标志来替代这个分支。
避免使用条件分支    mov bl,0
避免使用条件分支    
mov ecx,32
避免使用条件分支
count_loop:
避免使用条件分支    
shl eax,1
避免使用条件分支    
adc bl,0
避免使用条件分支    loop count_loop
Setxx指令提供了在一定情况下替换条件分支的方法。基于FLAGS寄存器的状态,这些指令将一个字节的寄存器或内存空间的值置为0或1.在SET后的字符与条件分支使用的是一样的。如果SETxx条件为真,那么储存的结果就是1,如果为假,则储存的结果就为0.例如
setz al   ;AL=如果ZF标志置位了则为1,否则为0
例如,考虑查找两个数的最大数的问题。这个问题的标准解决方法是使用一条CMP指令再使用条件分支对最大值进行操作。下面这个例子展示了不使用分支如何找到最大值。
避免使用条件分支%include "asm_io.inc"
避免使用条件分支
避免使用条件分支segment .data
避免使用条件分支message1    db    
"Enter a number: ",0
避免使用条件分支message2    db    
"Enter another number: ",0
避免使用条件分支message3    db    
"The larger number is: ",0
避免使用条件分支
避免使用条件分支segment .bss
避免使用条件分支input1    resd    
1
避免使用条件分支
避免使用条件分支segment .text
避免使用条件分支    global _asm_main
避免使用条件分支
_asm_main:
避免使用条件分支    
enter 0,0
避免使用条件分支    
pusha
避免使用条件分支
避免使用条件分支    
mov eax,message1
避免使用条件分支    
call print_string
避免使用条件分支    
call read_int
避免使用条件分支    
mov [input1],eax
避免使用条件分支
避免使用条件分支    
mov eax,message2
避免使用条件分支    
call print_string
避免使用条件分支    
call print_nl
避免使用条件分支
避免使用条件分支    
xor ebx,ebx
避免使用条件分支    
cmp eax,[input1]
避免使用条件分支    
setg bl        ;ebx=(input2>input1)?1:0
避免使用条件分支
    neg ebx        ;ebx=(input2>input1)?0xFFFFFFFF:0
避免使用条件分支
    mov ecx,ebx    ;ecx=(input2>input1)?0xFFFFFFFF;0
避免使用条件分支
    and ecx,eax    ;ecx=(input2>input1)?input2:0
避免使用条件分支
    not ebx        ;ebx=(input2>input1)?0:0xFFFFFFFF
避免使用条件分支
    and ebx,[input1];ebx=(input2>input1)?0:input1
避免使用条件分支
    or ecx,ebx    ;ecx=(input2>input1)?input2:input1
避免使用条件分支

避免使用条件分支    
mov eax,message3
避免使用条件分支    
call print_string
避免使用条件分支    
mov eax,ecx
避免使用条件分支    
call print_int
避免使用条件分支    
call print_nl
避免使用条件分支
避免使用条件分支    
popa
避免使用条件分支    
mov eax,0
避免使用条件分支    
leave
避免使用条件分支    
ret

这个诀窍就是产生一个可以用来选择出正确的最大值的掩码。另外一个可供选择的诀窍是使用DEC指令。在上面的代码中,如果用DEC代替NEG,那么结果同样是0或0xFFFFFFFF。但是,与使用NEG相比,得到值将是反过来的。

相关文章:

  • 2022-12-23
  • 2021-10-16
  • 2021-03-29
  • 2022-12-23
  • 2021-12-09
  • 2021-11-21
  • 2022-02-05
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-06-05
  • 2022-01-13
  • 2022-12-23
  • 2021-09-06
  • 2022-02-10
  • 2021-09-06
相关资源
相似解决方案