控制指令

控制指令条件码 CPU 维护一组单个位的条件码寄存器 CF 进位标志 最近的操作使最高位产生了进位 可用来检查无符号操作的溢出 ZF 零标志 最近的操作得出得结果为 0 SF 符号标志 最仅的操作得到的结果为负数 OF 溢出标志 最近的操作导致一补码溢出 正溢出或负溢出 leaq 指令是用来进行地址计算的 不改变任何条件码 指令 基于 描述 CMP

大家好,我是讯享网,很高兴认识大家。

条件码

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

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

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

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

访问条件码

指令 同义名 效果 设置条件
sete D setz D<—ZF 相等/零
setne D setnz D<—~ZF 不等/非零
sets D D<—SF 负数
setns D D<—~SF 非负数
setg D setnle D<— ~(SF^OF)&~ZF 大于(有符号>)
setge D setnl D<— ~(SF^OF) 大于等于(有符号>=)
setl D setnge D<— SF^OF 小于(有符号<)
setle D setng D<— (SF^OF) ZF
seta D setnbe D<—~CF&~ZF 超过(无符号>)
setae D setnb D<—~CF 超过或相等(无符号>=)
setb D setnae D<—CF 低于(无符号<)
setbe D setna D<—CF|ZF 低于或相等(无符号<=)

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

跳转指令

指令 同义名 跳转条件 描述
jmp Label 1 直接跳转
jmp *Operand 1 间接跳转
je Label jz ZF 相等/零
jne Label jnz ~ZF 不相等/非零
js Label SF 负数
jns Label ~SF 非负数
jg Label jnle ~(SF^OF)&~ZF 大于(有符号>)
jge Label jnl ~(SF^OF) 大于或等于(有符号>=)
jl Label jnge SF^OF 小于(有符号<)
jle Label jng (SF^OF)|ZF 小于或等于(有符号<=)
ja Label jnbe ~CF&~ZF 超过(无符号>)
jae Label jnb ~CF 超过或相等(无符号>=)
jb Label jnae CF 低于(无符号<)
jbe Label jna CF ZF

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, R cmovz ZF 相等/零
cmovne S, R cmovnz ~ZF 不相等/非零
cmovs S, R SF 负数
cmovns S, R ~SF 非负数
cmovg S, R cmovnle ~(SF^OF)&~ZF 大于(有符号>)
cmovge S, R cmovnl ~(SF^OF) 大于或等于(有符号>=)
cmovl S, R cmovnge SF^OF 小于(有符号<)
cmovle S, R cmovng (SF^OF)|ZF 小于或等于(有符号<=)
cmova S, R cmovnbe ~CF&~ZF 超过(无符号>)
cmovae S, R cmovnb ~CF 超过或相等(无符号>=)
cmovb S, R cmovnae CF 低于(无符号<)
cmovbe S, R cmovna CF|ZF 低于或相等(无符号<=)

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

小讯
上一篇 2025-02-07 10:47
下一篇 2025-02-08 20:00

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/19096.html