Intel有很多条件跳转指令,都是根据状态寄存器的值来裁决是否需要跳转的,一般的跳转,其判定原则是比较明显的,例如JZ就是ZF为1跳转,为0则不跳转。
而有符号数跳转命令JG,JL,JNG,JNL,JLE,JGE...的判定原则则不是那么的明显,先用JG作为例子分析之:
为何SF==OF且ZF==0表示a>b呢?
要求ZF==0好理解,如果ZF==1表示a==b,不满足a>b,故如果ZF必须是0
而要求SF==OF就不是那么的好理解了,需要分解成几个步骤来考虑:
可以看一下溢出(OF)或符号(SF)被置位的所有组合:
而有符号数跳转命令JG,JL,JNG,JNL,JLE,JGE...的判定原则则不是那么的明显,先用JG作为例子分析之:
CMP a, b; //假设a和b都是一个字节的参数
JG addr;
此时,JG跳转的条件是:SF==OF并且ZF==0
JG addr;
为何SF==OF且ZF==0表示a>b呢?
要求ZF==0好理解,如果ZF==1表示a==b,不满足a>b,故如果ZF必须是0
而要求SF==OF就不是那么的好理解了,需要分解成几个步骤来考虑:
- 如果SF是0,表示a-b是一个正数,这间接说明了a>b,这很好理解
- 如果SF是1,表示a-b是一个负数,似乎间接说明a<b,其实不然,我们需要考虑溢出的情况
可以看一下溢出(OF)或符号(SF)被置位的所有组合:
- a是正数,b是正数,a>b,此时a-b>0,SF==0, OF==0, SF==OF
- a是正数,b是负数,a>b,a-b=a-(-绝对值b)=a+绝对值b的结果小于等于127时,没有溢出,OF==0,此时SF==0,则SF==OF
- a是正数,b是负数,a>b,但a-b=a-(-绝对值b)=a+绝对值b的结果大于127时,导致上溢出(单字节最大的正数是127),同时导致SF==1(超过127时D7位为1),此时SF==OF
- a是0,b是-128,a>b,但a-b=0-(-128)=128,由于128>127,导致上溢出,同时导致SF==1(128即0x80,D7位为1),此时SF==OF
- a是负数,b是正数,a<b,a-b>=-128,没有导致下溢出,此时SF==1,OF==0,SF!=OF
- a是负数,b是正数,a<b,但a-b<-128导致下溢出(单字节最小的负数是-128),同时导致SF==0(0x80减正数导致结果小于0x80导致D7位为0),此时SF!=OF
- a是负数-128,b是0,a<b,a-b=-128-0=-128,此时没有下溢出,OF==0, SF==1,SF!=OF
- a是负数,b是负数,a>b则a-b>0且不可能溢出,则SF==0, OF==0,则SF==OF
- a是负数,b是负数,a<b,a-b<0且a-b>-128,此时没有溢出,则SF==1, OF==0, 则SF!=OF
- a是负数,b是负数,a<b,且a-b<-128,此时出现下溢出,则SF==0, OF==1,则SF!=OF