32位汇编语言学习笔记(11)--条件传送指令

时间:2021-10-03 14:43:31


条件传送指令如下:

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 //比较xy

       cmovl  %ebx, %eax //如果x小于yeax = 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 //比较xy

       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

 

两份汇编代码的区别是,一个使用了条件传送,另外一个使用了跳转指令。跳转指令需要处理器做分支预测,但是条件传送指令不需要,因此,使用条件传送指令的汇编代码效率要高一点。