计算机系统第三章——控制

控制:条件码
当前运行程序的相关信息
临时数据(%eax,…)
运行栈桢的地址(%ebp,%esp)
即将要执行的指令地址(%eip,…)
标志位
CF:是否有进位,无符号数加减法
ZF:结果是否为零
SF:第一位是否为1(有符号数),结果为负数
OF:结果是否溢出,有符号数有了溢出

条件码设置:cmpl Src,Dest Dest-Src影响标志位
比如比较两个有符号数的大小
使用cmpl l1,l2
如果l2<l1 SF^OF=1
l2>l1 SF^OF=0

testl b,a 等价于a&b设置条件码
判断该寄存器是否为0
ZF set 如果a&b==0
SF set 如果a&b<0 也就是有符号数自己与自己与,首位为1

SF^OF=1表示小于,后小于前
~(SF^OF)表示大于等于,后大于等于前
ZF表示相等,SF表示为负数
~SF表示非负数
(SF^OF)|ZF表示小于或者等于
CF&ZF表示无符号数大于,因为不需要借位,够减
CF就表示小于,要借位,不够减

movl 12(%ebp),%eax //eax=y
cmpl %eax,8(%ebp)//x-y,改变标志位
setg %al //al=x>y,就是如果x>y,al为1 //如果(SF^OF)&ZF
movzbl %al,%eax //因为al是eax低8位,我们将高24位置0

返回值一定要放在eax中
setg 只设置一个字节

条件分支
jmp无条件跳转
je/jz 当ZF=1时跳转,也就是相等或者等于0 cmpl %eax,%ebx //ebx和eax相等, text %eax,%eax//eax为0
jne/jnz 当ZF=0时跳转,就是不相等或者不等于0
js 当SF为1时跳转,就是为负数
jns 当SF为0时跳转,就是非负数
jg 当(SF^OF)&ZF就是大于
jge 当~(SF^OF)就是大于等于
jl 当(SF^OF)就是小于
jle 当(SF^OF)|ZF就是小于或者等于
ja 当CF&ZF无符号数大于above
jb 当C无符号小于below

条件跳转
先跳转再执行

分支跳转
val=x>y?x-y:y-x
先有分支,再跳转

条件传送:满足条件做传送
先计算一个条件操作的两种结果,然后根据条件选择某一个
int tval=y-x;
int rval=x-y;
int test=x<y;
if(test) rval=tval;
return rval;

cmpl %edx,%ecx
cmovl %ebx,%eax
当ecx小于edx,就将ebx传给eax
这样CPU就无需做分支预测,避免预测错误的代价,流水线效率更高

条件传送:要提前先算好
并且算的时候可能会有非法操作
两个表达式都进行了计算,对同一个变量进行计算,那么第二个引用的变量就是第一个计算完的了

循环:
do-while:先执行一遍循环体,再判断
while:先判断,再执行
for循环:先赋初值,再判断,再做循环体,再更新循环变量

switch语句:跳转表
long switch(long x)
{
long w=1;
switch(x)
{。。。
}
return w;
}
movl 8(%ebp),%eax//eax=x
cmpl $6,%eax //eax-6,更新标志位
ja .L8 如果大于就goto default
jmp *.L4(,%eax,4)//goto *JTab[x]每个跳转地址需要4字节
跳转表基地址:.L4

假如基地址为0x8048680
jmp *0x8048680(,%eax,4)
我们就可以用gdb查看跳转表的地址
x/7xw 0x8048680

计算机系统第三章——控制计算机系统第三章——控制