之前看到了cmp指令,总是记混。现在准备对CMP指令和汇编条件的判断做一个简单的总结。
CMP指令
- cmp(compare)指令进行比较两个操作数的大小
- 例:cmp oprd1,oprd2
- 当执行到CMP指令的时候会读取这两个寄存器的内容,并加以减法运算,结果本身不保留,并按照结果设置符号位(属算术运算)。
- 如何判断大小
若执行指令后:ZF=1,则说明两个数相等,因为zero为1说明结果为0.
当无符号时:
若CF=1,则说明了有进位或借位,cmp是进行的减操作,故可以看出为借位,所以,此时oprd1<oprd2;
CF=0,则说明了无借位,但此时要注意ZF是否为0,若为0,则说明结果不为0,故此时oprd1>oprd2.
当有符号时:
若SF=0,OF=0 则说明了此时的值为正数,没有溢出,可以直观的看出,oprd1>oprd2;
若SF=1,OF=0 则说明了此时的值为负数,没有溢出,则为oprd1<oprd2;
若SF=0,OF=1 则说明了此时的值为正数,有溢出,可以看出oprd1<oprd2;
若SF=1,OF=1则说明了此时的值为负数,有溢出,可以看出oprd1>oprd2;
最后两个可以作出这种判断的原因是,溢出的本质问题:
两数同为正,相加,值为负,则说明溢出
两数同为负,相加,值为正,则说明溢出
故有,正正得负则溢出,负负得正则溢出
所以说还是比较简单的一条指令。
补充: 两数相减,同号,则不溢出;两数为异号,结果与减数符号相同,则溢出。
符号位表
符号位 | 叙述 | 典型应用 |
OF | 溢出标志,标明一个溢出的运算。真置1,假置0。 | 这个溢出,非溢出,我想我还没有弄懂 |
SF | 负号标志,标明结果为负数。真置1,假置0。 | int i = -100; if(i < 0) goto somewhere; |
ZF | 零标志,标明结果为0。真置1,假置0。 | 见上cmp例子 |
CF | 进位标志,标明结果进位了。真置1,假置0。 | MOV EAX,1 MOV EBX,9 ADD EAX,EBX |
AF | 辅助进位标志,记录运算时第3位(半个字节)产生的进位。 | <null> |
PF | 奇偶标志,结果操作数中1的个数为偶置1(我猜是二进制下)。 | <null> |
DF | 方向标志,在串处理指令中控制信息的方向(非运算) | (null) |
IF | 中断标志(非运算) | (null) |
TF | 陷井标志(非运算) | (null) |
JCC指令表
- JCC指条件跳转指令,CC就是指条件码。
JCC指令 | 中文含义 | 英文原意 | 检查符号位 | 典型C应用 |
JZ/JE | 若为0则跳转; 若相等则跳转 | jump if zero; jump if equal | ZF=1 | if (i == j); if (i == 0); |
JNZ/JNE | 若不为0则跳转; 若不相等则跳转 | jump if not zero; jump if not equal | ZF=0 | if (i != j); if (i != 0); |
JS | 若为负则跳转 | jump if sign | SF=1 | if (i < 0); |
JNS | 若为正则跳转 | jump if not sign | SF=0 | if (i > 0); |
JP/JPE | 若1出现次数为偶数则跳转 | jump if Parity (Even) | PF=1 | (null) |
JNP/JPO | 若1出现次数为奇数则跳转 | jump if not parity (odd) | PF=0 | (null) |
JO | 若溢出则跳转 | jump if overflow | OF=1 | (null) |
JNO | 若无溢出则跳转 | jump if not overflow | OF=0 | (null) |
JC/JB/JNAE | 若进位则跳转; 若低于则跳转; 若不高于等于则跳转 | jump if carry; jump if below; jump if not above equal | CF=1 | if (i < j); |
JNC/JNB/JAE | 若无进位则跳转; 若不低于则跳转; 若高于等于则跳转; | jump if not carry; jump if not below; jump if above equal | CF=0 | if (i >= j); |
JBE/JNA | 若低于等于则跳转; 若不高于则跳转 | jump if below equal; jump if not above | ZF=1或CF=1 | if (i <= j); |
JNBE/JA | 若不低于等于则跳转; 若高于则跳转 | jump if not below equal jump if abow | ZF=0且CF=0 | if (i > j); |
JL/JNGE | 若小于则跳转; 若不大于等于则跳转 | jump if less jump if not greater equal | SF != OF | if (si < sj); |
JNL/JGE | 若不小于则跳转; 若大于等于则跳转; | jump if not less; jump if greater equal | SF = OF | if (si >= sj); |
JLE/JNG | 若小于等于则跳转; 若不大于则跳转 | jump if less equal; jump if not greater | ZF != OF 或 ZF=1 | if (si <= sj); |
JNLE/JG | 若不小于等于则跳转; 若大于则跳转 | jump if not less equal jump if greater | SF=0F 且 ZF=0 | if(si>sj) |