cmp⽐较指令对标志寄存器的影响
⽐如: mov ax,x
mov bx,y
cmp ax,bx
cmp ax,bx的逻辑含义是⽐较ax,bx中的值。如果执⾏后:
ZF=1则AX=BX
ZF=0则AX!=BX
CF=1则AX<BX
CF=0则AX>=BX
CF=0并ZF=0则AX>BX
CF=1或ZF=1则AX<=BX
CPU在执⾏cmp指令的时候,也包含两种含义:进⾏⽆符号运算和进⾏有符号数运算。
cmp ah,bh
如果ah=bh则ah-bh=0所以ZF=1
如果ah≠bh则ah-bh≠0所以ZF=0
所以我们根据cmp指令执⾏后ZF的值,就可以知道两个数据是否相等。如果ah<bh则可能发⽣什么情况呢?
对于有符号数运算,在ah>bh情况下,ah-bh显然可能引起SF=1既结果为负⽐如:
ah=1,bh=2则ah-bh=0FFH,0FFH为-1的补码,因为结果为负,所以SF=1。
ah=0FEH,bx=OFFH;则ax-bx=-2-(-1)=OFFH,因为结果为负,所以SF=1。
再看两个例⼦:
ah=22H,bh=OAOH则ah-bh=34-(-96)=82H,82H是-126的补码。
所以SF=1。这⾥虽然SF=1,但是并不能说明ah<bh因为显然34>-96
两个有符号数A和B相减,得到的是负数,那么可以肯定A<B这个思路没有错误,关键在于我们根据什么来断定得到的是⼀个负数,CPU将cmp指令得到的结果记录在flag的相关标志位中,我们可以根据指令执⾏后,相关标志位的值来判断⽐较的结果。单纯的考察SF的值不可能知道结果的正负。因为SF记录的只是可以在计算机中存放的相应位数的正负,cmp ah,bh执⾏后,SF记录的是ah-bh所得到的8位结果数据的正负,虽然这个结果没有在我们能够使⽤的寄存器或内存单元中保存,但是在指令执⾏的过程中,它暂存在cpu内存的暂存器中。
所得到的相应结果的正负,并不能说明,运算所应该得到的结果的正负。这是因为在运算的过程中可能发⽣溢出。如果这样的情况发⽣,那么SF的值就不能说明任何问题。⽐如
mov ah,22H
mov bh,0A0H
sub ah,bh
结果SF=1运算实际得到的结果是ah=82H,但是在逻辑上,运算所应该得到的结果是34-(-96)=130就是因为130这个结果作为⼀个有符号Y数超出了-128~127这个范围,在ah中不能表⽰,⽽ah中的结果被CPU当作有符号数解释为-126。⽽SF被⽤来记录这个实际结果的正负所以SF=1
⼜⽐如
mov ah,0A0H
mov bh,0CBH
cmp ah,bh
结果SF=1,运算ah-bh实际得到的结果是D5H但是在逻辑上,运算所应该得到的结果是160- -53=213,SF记录实际结果的正负,所以
SF=1。但SF=1不能说明在逻辑上运算所得到的正确结果。
但是逻辑上的结果的正负才是cmp指令所求的真正结果,因为我们就是要靠它得到两个操作对象的⽐较信息。所以cmp所做的⽐较结果,不是仅仅靠SF就能记录的,因为它只能记录实际结果的正负。
我们考虑下,两种结果之间的关系,实际结果的正负,和逻辑上真正结果的正负,它们之间有多⼤的距离呢?总上⾯的分析中我们知道,实际结果的正负,之所以不能说明逻辑上真正结果的正负,关键的原因在于发⽣了溢出。如果没有溢出发⽣的话,那么,实际结果的正负和逻辑上真正结果的正负就⼀致了。
所以我们应该在考察SF的同时考察OF旧可以得知逻辑上真正结果的正负同时就可以知道⽄毫秒度的结果。
下⾯我们以cmp ah,bh为例总结⼀下CPU执⾏cmp指令后SF和PF的值的如何来说明⽐较的结果的:
1)如果SF=1⽽OF=0说明没有溢出逻辑上真正结果的正负=实际结果的正负,因实际结果为负所以逻辑上真正的结果为负则ah<bh
2)如果SF=1⽽PF=0说明实际结果为负并且有溢出,则实际结果和真正结果不等,因SF=1实际结果为负。则:如果因为溢出导致了实际结果为负。那么逻辑上真正的结果必然为正。ah<bh比较指令cmp怎么用
3)如果SF=0⽽OF=1说明实际结果为正并且有溢出,则实际结果和真正结果不等,因SF=0,实际结果⾮负。则:如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。这样说明ah<bh
4)如果SF=0⽽OF=0说明没有溢出,逻辑上真正结果的正负=实际结果的正负,因SF=0实际结果⾮负,所以逻辑上真正的结果⾮负,所以ah>=bh