条件移动指令
64 位
int absdiff(int x, int y)
{
int result;
if (x > y)
{
result = x - y;
}
else
{
result = y - x;
}
return result;
}
如果我们把相同的这段代码, 放到 64 位环境下编译, 生成如下指令 :
absdiff :
;x in %edi, y in %esi
movl %edi, %eax ; v = x
movl %esi, %edx ; ve = y
subl %esi, %eax ; v -= y
subl %edi, %edx ; ve -= x
cmpl %esi, %edi ; x : y
cmovle %edx, %eax ; v = ve if <=
ret
注意它减了两次, 也就是说它把 x - y 和 y - x 两个值都算出来了, 无非是一个放到 eax 里面, 一个放到 edx 里面.
然后 cmpl 一下.
然后还用了一个我们不知道的指令. 这条指令是干嘛的呢 ? 我们可以猜测一下, 常规来讲, 生成的汇编代码里面应该会有个类似于条件跳转的东西. 但是现在没有条件跳转指令, 而是有一条 cmovle
这样的指令.
很明显这个是一条条件传送指令.
cmov 就是 conditional move 条件移动
cmovC src, dest
, 如果条件 C 成立, 将数据从 src 传送到 dest, 否则什么都不做.
这里的 Condition 就是上面那个大写的 C.
我们这里的就是 le. 这让我们想到了之前 set
jmp
指令的那些后缀.
这个意思就是 edi 和 esi 比一比, 如果小于等于的话, 我就把 edx 挪到 eax 里面去, 否则就什么都不做.
我们从执行的角度来看, 条件传送指令效率比一般的条件跳转指令效率高, 因为其控制流可以预测 (就是条件 C 是已知的).