深入理解计算机系统——第三章—3.6控制

3.6 控制(control)

jump指令可以改变一组机器代码指令的执行顺序。

3.6.1 条件码(condition code)

条件码寄存器。
CF(carry flag): 进位标志。最近的操作使最高位产生了进位。可用来检查无符号操作的溢出。
ZF(zero flag)零标志。最近的操作得出的结果为零。
SF(signed flag)符号标志。最近的操作得到的结果为负数。
OF(overflow flag)溢出标志。最近的操作导致一个补码溢出——正溢出或负溢出。

标志(flag 执行 效果
CF (unsigned) t < (unsigned) a 无符号溢出
ZF t == 0
SF t < 0 负数
OF a < 0 == b < 0 && (t < 0 != a<0 有符号溢出

leaq 指令不会改变任何条件码,因为它是用来进行地址计算的。
这里写图片描述

3.6.2 访问条件码

条件码通常不会直接读取,常用的使用方法有三种:
1) 可以根据条件码的某种组合,将一个字节设置为 0 或者 1;
2)可以条件跳转到程序的某个其他的部分;
3)可以有条件地传送数据。
这里写图片描述

3.6.3 跳转指令

这里写图片描述

3.6.4 跳转指令的编码

这里写图片描述
这里写图片描述

3.6.5 用条件控制来实现条件分析

将条件表达式和语句从C语言翻译成机器代码,最常用的方式就结合有条件和无条件跳转。
这里写图片描述
C语言中的 if-else 语句的通用形式模版如下:

if (test-expr)
    then-statement
else
    else-statement

对应汇编实现通常会使用下面这种形式。以C语言语法来描述控制流:

t = test-expr;
if (!t)
    goto false;
then-statement;
goto done;
false:
    else-statement;
done:

3.6.6 用条件传送来实现条件分支

实现条件操作的传统方法是通过使用控制的条件转移(条件满足,执行A;否则执行B)。
一种替代的策略是使用数据的条件转移(在一定条件下,事先把条件结果列出来,根据条件直接选取数据结果来执行下一路径)。
示例(ret 返回的参数存放在 %rax 中):
这里写图片描述
分支预测错误的处罚
这里写图片描述
条件传送指令
这里写图片描述
这里写图片描述
如果条件分支中任意一个可能产生错误条件或者副作用,将会导致非法的行为。
这里写图片描述

3.6.7 循环

1. do-while 循环

这里写图片描述
这里写图片描述
这里写图片描述

2. while 循环

在这里插入图片描述
第一种翻译方法(jump to middle
在这里插入图片描述
示例:
在这里插入图片描述
第二种翻译方法(guarded-do
这里写图片描述
示例:
这里写图片描述
这里写图片描述
有趣的特性。循环测试(汇编代码的第9行)从原始C代码的 n>1 变成了 n != 1 。编译器知道只有当 n > 1时才进入循环,所以将 n1意味着n > 1或者n = 1。因此,测试n != 1 就等价于测试n >= 1。(本人未验证)

3. for 循环

for 循环的通用格式:

for (init-expr; test-expr; update-expr)
    body-statement

等价于:

init-expr:
while(test-expr){
    body-statement
    update-expr;
}

跳转到中间的策略 goto 代码:

    init-expr;
    goto test;
loop:
    body-statement;
    update-expr;
test:
    t = test-expt;
    if(t)
        goto loop;

而 guarded-do 策略得到:

    init-expr;
    t = test-expr;
    if(!t)
        goto done;
loop:
    body-statement;
    t = test-expt;
    if(t)
        goto loop;
done:

这里写图片描述
综上所述,C语言中三种形式的所有循环——do-whilewhile、和for都可以用一种简单的策略来翻译,产生包含一个或多个条件分支的代码。控制的条件转移提供将循环翻译成机器代码的基本机制。

3.6.8 switch 语句

switch(开关)语句可以根据一个整数索引值进行多重分支(multiway branching)。
跳转表是一个数组,表项 i 是一个代码段的地址,这个代码段实现当开关索引值等于 i 时程序应该采取的动作。
示例:
这里写图片描述
这里写图片描述
跳转表
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章