第十一章:标志寄存器04
让编程改变世界
Change the world by program
cmp指令
下面我们再来看一下如果用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)=0FFH: 则(ah)-(bh)=(-2)-(-1)=0FFH,因为结果为负,所以SF=1。 通过上面的例子,我们是不是可以得到这样的结论: cmp 操作对象1,操作对象2 指令执行后,SF=1,就说明操作对象1<操作对象2?当然不是!! 我们再看下面这个例子。 (ah)=22H,(bh)=0A0H: 则(ah)-(bh)=34-(-96)=130=82H,82H是 -126的补码,所以SF=1。 这里虽然SF=1,但是并不能说明(ah)<(bh),因为显然34>-96。 两个有符号数A 和B 相减,得到的是负数,那么可以肯定A<B,这个思路没有错误; 关键在于我们根据什么来断定得到的是一个负数。 CPU将 cmp 指令得到的结果记录在flag的相关标志位中。 我们可以根据指令执行后,相关标志位的值来判断比较的结果。 单纯地考察SF 的值不可能知道结果的正负。因为SF 记录的只是可以在计算机中存放的相应位数的结果的正负。 比如add ah, al执行后,SF记录的是ah中的8位二进制信息所表示的数据的正负。 所得到的相应结果的正负,并不能说明,运算所应该得到的结果的正负。 这是因为在运算的过程中可能发生溢出。 如果有这样的情况发生,那么,SF的值就不能说明任何问题。 如果没有溢出发生的话,那么,实际结果的正负和逻辑上真正结果的正负就一致了。 所以,我们应该在考察SF(得知实际结果的正负)的同时考察OF(得知有没有溢出),就可以得知逻辑上真正结果的正负,同时就可以知道比较的结果。 下面,我们以cmp ah,bh为例,总结一下CPU执行cmp指令后,SF和OF的值是如何来说明比较的结果的。 (1)如果SF=1,而OF=0 OF=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负; 因SF=1,实际结果为负,所以逻辑上真正的结果为负,所以(ah)<(bh)。 (2)如果SF=1,而OF=1 OF=1 ,说明有溢出,逻辑上真正结果的正负≠实际结果的正负; 简单分析一下,就可以看出,如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正。这样,SF=1,OF = 1 ,说明了(ah)>(bh)。 (3)如果SF=0,而OF=1 OF=1 ,说明有溢出,逻辑上真正结果的正负≠实际结果的正负; 简单分析一下,就可以看出,如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。这样,SF=0,OF = 1 ,说明了(ah)<(bh)。 (4)如果SF=0,而OF=0 OF=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负; 因SF=0,实际结果非负,所以逻辑上真正的结果必然非负。所以(ah)≥(bh)。 上面,我们深入讨论了cmp指令在进行有符号数和无符号数比较时,对flag 相关标志位的影响,和CPU如何通过相关的标志位来表示比较的结果。 在学习中,要注意领会8086CPU这种工作机制的设计思想。实际上,这种设计思想对于各种处理机来说是普遍的。检测比较结果的条件转移指令
下面的内容中我们将学习一些根据cmp指令的比较结果(即,cmp指令执行后,相关标志位的值)进行工作的指令。它们检测的是哪些标志位呢?
(一)就是被cmp指令影响的那些,表示比较结果的标志位。 (二)这些条件转移指令通常都和cmp相配合使用,就好像 call 和 ret 指令通常相配合使用一样。 因为 cmp 指令可以同时进行两种比较,无符号数比较和有符号数比较,所以根据 cmp 指令的比较结果进行转移的指令也分为两种,即: 根据无符号数的比较结果进行转移的条件转移指令,它们检测ZF、CF的值; 和根据有符号数的比较结果进行转移的条件转移指令,它们检测 SF、OF和 ZF的值。条件转移指令小结
[caption id="attachment_393" align="aligncenter" width="300"]
e:表示equal;
ne:表示not equal;
b:表示below;
nb:表示not below;
a:表示above;
na:表示not above。
注意观察一下它们所检测的标志位,都是cmp指令进行无符号数比较时候,记录比较结果的标志位。 比如je,检测 ZF位,当 ZF=1的时候进行转移,如果在 je 前面使用了 cmp 指令,那么je对ZF的检测,实际上就是间接地检测cmp的比较结果是否为两数相等。