条件传送指令如下:
cmove S, D //等于0时传送
cmovz S, D //同cmove
cmovne S, D //不等于0时传送
cmovnz S, D //同cmovne
cmovs S, D //负数时传送
cmovns S, D //非负数时传送
cmovg S, D //有符号大于时传送
cmovnle S, D //同cmovg
cmovge S, D //有符号大于等于时传送
cmovnl S, D //同cmovge
cmovl S, D //有符号小于时传送
cmovnge S, D //同cmovl
cmovle S, D //有符号小于等于时传送
cmovng S, D //同cmovle
cmova S, D //无符号大于时传送
cmovnbe S, D //同cmova
cmovae S, D //无符号大于等于时传送
cmovnb S, D //同cmovae
cmovb S, D //无符号小于时传送
cmovnae S, D //同cmovb
cmovbe S, D //无符号小于等于时传送
cmovna S, D //同cmovbe
示例:
int absdiff(int x, int y)
{
return x < y ? y-x : x-y;
}
gcc -O1 -S -m32-march=i686 test_absdiff.c
absdiff:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl 8(%ebp), %ecx //ecx = x
movl 12(%ebp), %edx //edx = y
movl %edx, %ebx //ebx = y
subl %ecx, %ebx //ebx = y - x
movl %ecx, %eax //eax = x
subl %edx, %eax // eax = x -y
cmpl %edx, %ecx //比较x和y
cmovl %ebx, %eax //如果x小于y,eax = ebx = y -x
popl %ebx
popl %ebp
ret
如果不添加-march=i686,生成汇编代码如下:
absdiff:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx //edx = x
movl 12(%ebp), %eax //eax = y
cmpl %eax, %edx //比较x和y
jge .L2 //如果x大于等于y,跳转到L2
subl %edx, %eax //eax = y - x
jmp .L4 //跳转到L4
.L2:
subl %eax, %edx //edx = x - y
movl %edx, %eax //eax = edx = x- y
.L4:
popl %ebp
ret
两份汇编代码的区别是,一个使用了条件传送,另外一个使用了跳转指令。跳转指令需要处理器做分支预测,但是条件传送指令不需要,因此,使用条件传送指令的汇编代码效率要高一点。