控制指令

条件码

CPU维护一组单个位的条件码寄存器
- CF:进位标志。最近的操作使最高位产生了进位。可用来检查无符号操作的溢出。
- ZF:零标志。最近的操作得出得结果为0。
- SF:符号标志。最仅的操作得到的结果为负数。
- OF:溢出标志。最近的操作导致一补码溢出——正溢出或负溢出。

leaq指令是用来进行地址计算的,不改变任何条件码。

指令基于描述
CMP S1, S2S2 - S1比较
cmpb比较字节
cmpw比较字
cmpl比较双字
cmpq比较四字
TEST S1, S2S1 & S2测试
testb测试字节
testw测试字
testl测试双字
testq测试四节

比较和测试指令。这些指令不修改任何寄存器的值,只设置条件码

访问条件码

指令同义名效果设置条件
sete DsetzD<—ZF相等/零
setne DsetnzD<—~ZF不等/非零
sets DD<—SF负数
setns DD<—~SF非负数
setg DsetnleD<— ~(SF^OF)&~ZF大于(有符号>)
setge DsetnlD<— ~(SF^OF)大于等于(有符号>=)
setl DsetngeD<— SF^OF小于(有符号<)
setle DsetngD<— (SF^OF)ZF
seta DsetnbeD<—~CF&~ZF超过(无符号>)
setae DsetnbD<—~CF超过或相等(无符号>=)
setb DsetnaeD<—CF低于(无符号<)
setbe DsetnaD<—CF|ZF低于或相等(无符号<=)

SET指令。每条指令根据条件码的某种组合,将一个字节设置为0或者1。有些指令有” 同义名” ,也就是同一条机器指令有别的名字。

跳转指令

指令同义名跳转条件描述
jmp Label1直接跳转
jmp *Operand1间接跳转
je LabeljzZF相等/零
jne Labeljnz~ZF不相等/非零
js LabelSF负数
jns Label~SF非负数
jg Labeljnle~(SF^OF)&~ZF大于(有符号>)
jge Labeljnl~(SF^OF)大于或等于(有符号>=)
jl LabeljngeSF^OF小于(有符号<)
jle Labeljng(SF^OF)|ZF小于或等于(有符号<=)
ja Labeljnbe~CF&~ZF超过(无符号>)
jae Labeljnb~CF超过或相等(无符号>=)
jb LabeljnaeCF低于(无符号<)
jbe LabeljnaCFZF

jump指令。当跳转条件满足时,这些指令会跳转到一条带标号的目的地。有些指令有” 同义名 “,也就是同一条机器指令的别名

跳转目的地通常用一个标号(Label)指明,类似 “.L1” 。跳转有直接跳转”jmp .L1”或者间接跳转”jmp *%rax”用寄存器和内存中的值作为跳转目标。

跳转指令的编码可以用绝对地址或相对地址,相对地址利用jmp指令后面对应的值+下一条指令的起始地址=跳转目的地,这也方便程序在内存中的移动,最为常用。使用如下例:

   movq  %rdi, %rax
   jmp   .L2
.L3:
   sarq  %rax
.L2:
   testq  %rax, %rax
   jg     .L3
   rep; ret

汇编器产生的 ” .o ” 格式的反汇编版本如下:

0:48 89 f8               mov  %rdi, %rax
3:eb 03                  jmp  8 <loop+0x8>
5:48 d1 f8               sar  %rax
8:48 85 c0               test %rax, %rax
b:7f f8                  jg   5 <loop+0x5>
d:f3 c3                  repz retq
  • 对于jmp 8; 用 0x03(二进制补码)+5 = 0x8 即可得到跳转到8
  • 对于jg 5; 用 0xf8(二进制补码)+0xd = 0x5 即可得到跳转到5

现代使用条件传送来实现条件分支

long absdiff(long x, long y)
{
        long result;
        if(x < y)
                result = y-x;
        else
                result = x-y;
        return result;
}

优化的汇编

long absdiff(long x, long y)
x in %rdi, y in %rsi
absdiff:
        movq    %rsi, %rdx
        subq    %rdi, %rdx      rval = y-x
        movq    %rdi, %rax
        subq    %rsi, %rax      eval = x-y
        cmpq    %rsi, %rdi      compare x:y
        cmovl   %rdx, %rax      if x<y, eval = rval 
        ret                      return eval

以上汇编的实现原理可以使用如下的C语言来解释

long cmovdiff(long x, long y)
{
        long rval = y-x;
        long eval = x-y;
        long ntest = x >= y;
        /* Line below requires
         * single instruction: */
        if(ntest) 
                rval = eval;
        return rval;
}

条件传送指令

指令同义名传送条件描述
cmove S, RcmovzZF相等/零
cmovne S, Rcmovnz~ZF不相等/非零
cmovs S, RSF负数
cmovns S, R~SF非负数
cmovg S, Rcmovnle~(SF^OF)&~ZF大于(有符号>)
cmovge S, Rcmovnl~(SF^OF)大于或等于(有符号>=)
cmovl S, RcmovngeSF^OF小于(有符号<)
cmovle S, Rcmovng(SF^OF)|ZF小于或等于(有符号<=)
cmova S, Rcmovnbe~CF&~ZF超过(无符号>)
cmovae S, Rcmovnb~CF超过或相等(无符号>=)
cmovb S, RcmovnaeCF低于(无符号<)
cmovbe S, RcmovnaCF|ZF低于或相等(无符号<=)

条件传送指令。当传送条件满足时,指令把源值S复制到目的R。有些指令是” 同义名” ,即同一条机器指令的不同名字

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值