我们知道条件转移指令一般都是根据标志寄存器中某些位的状态来决定转移与否的,例如指令"JZ/JNZ"就是根据"ZF"标志判断条件的。JB指令也是符合这个规律的,它的转移条件是"借位/进位"标志CF=1。CMP指令实际是将相比较的两个数进行一次减法,很明显如果前一个数小于后一个数,相减时必然有一次"借位",所以指令JB实际应写成"JC(Jump if Carry)"指令JA的转移条件就有些特殊了,它要根据标志寄存器中两个位的状态判断条件,这两个位是"借位/进位"标志CF和"零"标志ZF,具体的条件是CF AND ZF=0,也就是CF和ZF这两位都是0的情况下指令JA才会执行转移。这相当于排除了两个数相等的情况。下面我们就来看看两个符号相同的数做减法运算后标志寄存器的变化:
C:\ASM\>DEBUG[Enter] -a[Enter] 13CD:0100 mov ax,100 13CD:0103 mov bx,200 13CD:0106 cmp ax,bx 13CD:0108 sub bx,ax 13CD:010A sub ax,bx 13CD:010C -r AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13CD ES=13CD SS=13CD CS=13CD IP=0100 NV UP EI PL NZ NA PO NC 13CD:0100 B80001 MOV AX,0100 注意ZF、CF两标志
首先利用"MOV"指令将100H与200H分别置入AX和BX而寄存器。
-t AX寄存器置入100H AX=0100 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13CD ES=13CD SS=13CD CS=13CD IP=0103 NV UP EI PL NZ NA PO NC 13CD:0103 BB0002 MOV BX,0200 BX寄存器置入200H
设置好AX、BX寄存器后即可以观察CMP等指令对标志寄存器的影响。
-t AX、BX寄存器已设置 AX=0100 BX=0200 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13CD ES=13CD SS=13CD CS=13CD IP=0106 NV UP EI PL NZ NA PO NC 13CD:0106 39D8 CMP AX,BX CMP指令的实质是一次减法
CPU在执行CMP指令时会将AX和BX两寄存器进行一次减法,但结果并不保留。只是标志寄存器会依据相减的结果发生变化。由于AX寄存器中的数值小于BX寄存器,所以我们可以想到指令执行后CF标志将有变化。
-t AX=0100 BX=0200 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13CD ES=13CD SS=13CD CS=13CD IP=0108 NV UP EI NG NZ NA PE CY 13CD:0108 29C3 SUB BX,AX小的数减大的数产生借位
下面的根踪反映了大的数减去小的数时标志寄存器的变化情况,可以清楚地看到刚刚变成"CY"的CF标志位又重新置成"NC"。
-t AX=0100 BX=0100 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13CD ES=13CD SS=13CD CS=13CD IP=010A NV UP EI PL NZ NA PE NC 13CD:010A 29D8 SUB AX,BX 大的数减小的数没有产生借位
最后一个SUB指令反映了相等的两个数相减时ZF标志位的变化情况,此情况前文已有所讨论。
-t AX=0000 BX=0100 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=13CD ES=13CD SS=13CD CS=13CD IP=010C NV UP EI PL ZR NA PE NC 13CD:010C 745B JZ 0169 相等两个数相减ZF标志发生变化
通过以上跟踪结果可以清楚地看到当用100H和200H相比较时(CPU实际执行100H-200H)CF标志置位,NC变为CY。这说明小的无符号数减大的无符号数时只有CF置位,因此JB指令的转移条件是CF=1;当我们用200H减去100H时,可以看到CF标志复位(置零)。好象这里面没有ZF的事,指令JA只需判断CF的状态就成了,其实不然。请看当用100H-100H时CF仍置零,而ZF却置成了1。可见如果仅判断CF标志,那么无论是"高于"(Above)还是"为零"(Zero)指令都要完成转移,这显然不是JA指令的含义。