汇编条件判断整理(JCC,CMP/TEST的实现) |
您所在的位置:网站首页 › ja和jg指令的条件都是大于 › 汇编条件判断整理(JCC,CMP/TEST的实现) |
比较的实现
我们知道CMP是比较两个寄存器内容的指令,但这是如何实现的? 当执行到CMP指令的时候会读取这两个寄存器的内容,并加以减法运算,结果本身不保留,并按照结果设置符号位(属算术运算)。 CMP是一个经常使用的指令,大多用来测试数字的大小。一个常见的例子 MOV EAX, 10 MOV EAX, 10 CMP EAX, EBX ;相减求出结果,为0,将1存入ZF JE SOME_WHERE ;检查ZF,为1就跳 JNE SOME_WHERE ;检查ZF,为0就跳当执行到TEST指令的时候会读取这两个寄存器的内容,并加以按位与运算,结果不保留,并按照结果设置符号位(属逻辑运算)。 TEST是一个用来检测内容而不是运算内容的,经常用的一招是测试寄存器是否为0: TEST EAX, EAX JZ SOME_WHERE某个参考资料说 TEST EAX,EBX 与 AND EAX,EBX 是一样的,窃以为不同,因为汇编的所有算术指令都是破坏性的,它会把结果存入 EAX,而TEST不会(就像C代码 a &= b;)。若要 AND 也不会破坏原值,只能先入栈存值,然后在出栈前转移结果,就像如下所示: MOV EAX, ?? ;赋值 MOV EBX, ?? PUSH EAX ;入栈保存EAX AND EAX, EBX ;运算 MOV EDX, EAX ;保存结果 POP EAX ;弹出恢复EAX但是你要自己做一个CMP指令是不切实际的,因为你自己还是要判断符号位的值,最终还是用到了TEST, CMP这些指令。 符号位表这些符号位存在一个叫做PSW(Program Status Word,程序状态字)的16位(4字节)寄存器里面。 符号位 叙述 典型应用 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位(半个字节)产生的进位。 PF 奇偶标志,结果操作数中1的个数为偶置1(我猜是二进制下)。 DF 方向标志,在串处理指令中控制信息的方向(非运算) (null) IF 中断标志(非运算) (null) TF 陷井标志(非运算) (null)其中前几个称为运算条件码(condition code),后三个是逻辑控制标志位,我们在此对它们不感兴趣。 JCC指令表JCC指条件跳转指令,CC就是指条件码。 JCC指令 中文含义 英文原意 检查符号位 典型C应用 JZ/JE若为0则跳转; 若相等则跳转 jump if zero; jump if equal ZF=1if (i == j); if (i == 0); JNZ/JNE若不为0则跳转; 若不相等则跳转 jump if not zero; jump if not equal ZF=0if (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); 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)这里有好多相等的指令(啊哈,这里有一个有意思的现象,好多看似不沾边的东西实际上是相等的!),我猜是因为编译器编译起来就更方便了,不过做一个表也没什么难的,这个结论不成立啊…… 这里有一点要指出,无符号数用低于、高于来比较,而有符号数用大于、小于比较。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |