80x86 汇编(gnu 语法)

Posted by persuez on May 8, 2019

比较

比较是基于减法的指令,但是减法的结果并不会存储,比较的结果会根据减法的结果来设置 FLAGS 寄存器。执行指令 cmp vleft, vright,会先计算 vright - vleft(注意减法的顺序,这和 Intel 相反,相当于 Intel 的 cmp vright, vlef),然后按照下面的规则设置 flag 位:

  • 对于无符号整数:FLAGS 寄存器中有两个位是重要的:ZF(zero flag) 和 CF(carry flag),其中 ZF 是在差值为 0 时被设置(值为 1),CF 是在减法发生借位时设置。即,如果 vright = vleft,ZF 将被设置为 1, CF 为 0;如果 vright > vleft,ZF 为 0,CF 为 0;如果 vright < vleft,ZF 为 0, CF 为 1。
  • 对于有符号整数:FLAGS 寄存器中有三个位是重要的:ZF,OF(overflow flag) 和 SF(sign flag),其中 ZF 是在差值为 0 时被设置,OF 是在减法发生溢出(overflow 或 underflow)时被设置,SF 是减法结果为负数时被设置。要理解接下来的内容,必须要知道什么情况下会发生溢出。当长度为n位的两个二进制数经过加减法器运算,得到的长度为n位的结果不是正确值时,我们说发生溢出。[1]减法溢出[2]只有两种情况:[正] - [负] ==》 [负][负] - [正] ==> [正]。所以, 如果 vright = vleft,ZF 被设置;如果 vright > vleft,则 ZF 为 0, SF = OF(如果没有溢出,则结果正确为正数,那么 SF = OF = 0;如果发生溢出,则结果为负数,那么 SF = OF = 1);如果 vright < vleft,那么 ZF 为 0,SF $\neq$ OF。

    参考文献

    1. 算数溢出
    2. 计算机判断溢出的原理?