1_条件码

条件码

Control Flow (控制流)

围绕条件码的设置和读取, 以及根据条件码来实现 C 语言的典型程序控制流, 包括 if-then-else, 循环结构和 switch 语句等等

然后我们就像往常一样, 把它扩展到 64 位架构

条件码_

条件码共分成四位, 你可以理解为是四个一位的寄存器, 每个里面就存储了这些标志位

CF : Carry Flag (进位位)

SF : Sign Flag (符号位)

ZF : Zero Flag (0 位), 就是你的计算结果是不是 0, 由它来标识

OF : Overflow Flag (溢出位)

当我们完成一条指令的时候, 这种指令往往是算术运算或者逻辑运算, 这些运算的结果, 它们隐含的状态信息, 就涉及在这些条件码中.

举个例子, 我们做一个加法运算 addl Src, Dest, addq Src, Dest, 就是类似于 C 语言 t = a + b; //a = Src, b = Dest 的运算.

  • 如果结果是 0 的话, 就把 ZF 设为 1.

  • 如果发生进位的话, 就把 CF 设为 1.
    可用于检测无符号整数运算的溢出

  • 如果相加出现了负数, 就把 SF 设置为 1, 我们把它当成带符号数处理了.

  • 如果这两个数当作带符号整数进行处理的话, 那么它们就作为补码运算. 如果这个时候补码运算出现了溢出, 就把 OF 设为 1.

    • 那么补码运算什么时候出现溢出呢. 如果两个正数相加都比较大, 一加, 产生溢出, 变成负的了; 或者说两个负数相加, 那么有可能变成正的, 这就叫溢出.

    最高位与次高位进位状态不一样, 就会产生溢出.

    最高位与次高位同时进位, 或者说进位状态一样, 这不叫溢出.

    CF=1, OF=1 表示无符号数和有符号数均溢出

实际上 CF 位和 OF 位联合起来考虑很有意思. 一个整数, 你是带符号还是不带符号, 在机器层面, 它的表示都是一样的, 因为补码的特性, 你对它进行简单的加减运算, 针对 add 而言, 它是不区分你是带符号还是不带符号的整型.

但是 add 指令它做完之后, 或者说在它做的同时, 它会判断两个进位标志, 就是 CF 和 OF. 就是说, 如果一方面把它作为无符号整数, 它溢出了, 就会设置 CF; 如果一方面把两个数作为带符号整数, 它溢出了, 就会设置 OF.

编译器通过这两个条件码判断溢出.