标志寄存器04 零基础入门学习汇编语言57

第十一章:标志寄存器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"] 条件转移指令小结[/caption]   这些指令比较常用,它们都很好记忆,它们的第一个字母都是j,表示jump;后面的:

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的比较结果是否为两数相等。  

编程训练

编程实现如下功能: 如果(ah)=(bh)则(ah)=(ah)+(ah), 否则(ah)=(ah)+(bh)。 [buy] 获得所有教学视频、课件、源代码等资源打包 [/buy] [Downlink href='http://kuai.xunlei.com/d/LJPGGTZRKAPI']视频下载[/Downlink]
原文地址:https://www.cnblogs.com/LoveFishC/p/3847031.html