标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作用: 1) 用来存储相关指令的某些执行结果;2) 用来为CPU执行相关指令提供行为依据;3) 用来控制CPU的相关工作方式. 这种特殊的寄存器在8086CPU中,被称为标志寄存器. 8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW). 我们已经使用过8086CPU的ax、bx、cx、dx、si、di、bp、sp、IP、cs、ss、ds、es等13个寄存器,现在我们再来学习最后一个标志寄存器(以下简称flag). flag和其他寄存器不一样,其他寄存器用来存放数据的,都是整个寄存器具有一个含义. 而flag寄存器是按位作用的,也就是说,它的每一位都有专门的含义,记录特定的信息. 8086CPU的flag寄存器的结构图如图1所示:
图1 flag寄存器各位示意图 flag的1、3、5、12、13、14、15位在8086CPU中没有使用,不具有任何含义. 而0、2、4、6、7、8、9、10、11位都具有特殊的含义. 在debug调式工具中,怎么查看标志寄存器的各个位标志呢? 打开调试工具,如图1绿线部分即为标志位:
图1 标志寄存器的标志位 1 ZF标志 flag的第6位是ZF,零标志位. 它记录相关指令执行后,其结果是否为0. 如果结果为0,那么zf = 1; 如果结果不为0,那么zf = 0. 比如,指令: 执行后,结果为0,则zf = 1. 执行后,结果不为0,则zf = 0. 对于zf的值,我们可以这样看,zf标记相关指令的计算结果是否为0,如果为0,则zf要记录下”是0″这样肯定的信息. 在计算机中1表示逻辑真,表示肯定,所以当结果为0时,zf = 1,表示”结果是0″. 如果结果不为0,则zf要记录下”不是0″这样的否定信息. 在计算机中0表示逻辑假,表示否定,所以当结果不为0时,zf = 0,表示”结果不为0″. 比如,指令: 执行后,结果为0,则zf = 1,表示”结果是0″. 执行后,结果不为0,则zf = 0,表示”结果非0″. 注意:在8086CPU的指令集中,有的指令执行是影响标志寄存器,比如,add、sub、mul、div、inc、or、and等,它们都是运算指令(进行逻辑或算术运算);有的指令的执行对标志寄存器没有影响,比如:mov、push、pop等,它们大都是传送指令. 在使用一条指令时,要注意这条指令的全部功能,其中包括执行结果对标志寄存器的哪些标志造成影响. 2 PF标志 flag的第2位是PF,奇偶标志位. 它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数. 如果1的个数为偶数,pf = 1,如果为奇数,那么pf = 0. 比如,指令: 执行后,结果为00001011B,其中有3(奇数)个1,则pf = 0; 执行后,其结果为00000011B,其中2(偶数)个1,则pf = 1; 执行后,结果为00000000B,其中有0(偶数)个1,则pf = 1. 3 SF标志 flag的第7位是SF,符号标志位. 它记录相关指令执行后,其结果是否为负. 如果结果为负,sf = 1;如果非负,sf = 0. 计算机通常用补码来表示有符号数据. 计算机中的一个数据可以看作有符号数,也可以看作无符号数. 比如: 也就是说,同一个二进制数据,计算机可以将它当作无符号数据来运算,也可以当作有符号数据来运算. 比如: 可以将add指令进行的运算当作无符号数的运算,那么add指令相当于计算129+1,结果为130(B);也可以将add指令进行的运算当作有符号数的运算,那么add指令相当于计算-127+1,结果为-126(B). 不管我们如何看待,CPU在执行add等指令时,就已经包含了两种含义,也将得到用同一种信息来记录的两种结果. 关键在于我们的程序需要哪一种结果. SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负. 在我们将数据当作有符号数来运算时,可以通过它来得知结果的正负. 如果我们将数据当作无符号数来运算,SF的值没有意义,虽然相关的指令影响了它的值. 这也就是说,CPU在执行add等指令时,是必然影响到SF标志位的值的. 至于我们需不需要这种影响,那就看我们如何看待指令所进行的运算了. 比如: 执行后,结果为B,sf = 1,表示:如果指令进行的是有符号运算,那么结果为负. 执行后,结果为0,sf = 0,表示:如果进行的是有符号数运算,那么结果为非负. 某些指令影响标志寄存器中的多个标记位,这些被影响的标志位比较全面地记录了指令的运行结果,为相关的处理提供了所需的依据. 比如指令sub al, al执行后,ZF、PF、SF等标志位都要受到影响,它们分别为1、1、0. 检测点 1: 写出下面每条指令执行后,ZF、PF、SF等标志位的值. 分析: add、sub、mul、div、inc、or、and等指令,它们大都为运算指令(进行逻辑或算术运算),会影响标志寄存器的状态. 而 mov、push、pop等,它们大都是传送指令,对标志寄存器没有影响. 答案如下: 注:指令 mul al,其计算结果存储在ax中,所以要根据ax来判断标志位,而非al. 4 CF 标志位 flag的第0位是CF,进位标志位. 一般情况下,在进行无符号运算时,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值. 对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N-1位,就是它的最高有效位,而假想存在的第N位,就是相对于最高有效位的更高位,如图1所示:
图1 更高位 我们知道,当两个数据相加时,有可能产生最高有效位向更高位的进位. 比如,两个8位数据:98H+98H,将产生进位. 由于这个进位值在8位数中无法保存,我们在前面中说过,就只是简单地说这个进位值丢失了. 其实CPU在运算时,并没有丢失这个进位值,而是记录在一个特殊的寄存器的某一位上. 8086CPU就用CF位来记录这个进位值. 比如,下面的指令: 我们可在debug中查看上面指令执行后,标志寄存器的状态,如图2所示:
图2 CF标志 而当两个数据做减法时,有可能向更高位借位. 比如,两个8位数据:97H~98H,将产生借位,借位后,相当于计算97H-98H. 而flag的CF位也可以用来记录这个借位值. 比如,下面的指令: 5 OF 标志 在进行有符号运算时,如结果超出了机器所能表示的范围称为溢出. 那么,什么是机器所表示的范围呢? 比如说,指令运算的结果用8位寄存器或内存单来存放,比如,add al, 3,那么对于8位的有符号数据,机器所能表示的就是-128~127. 同理,对于16位有符号数据,机器所能表示的范围是-32768~32767. 如果运算结果超出了机器所能表表达的范围,将产生溢出. 注意,这里所讲的溢出,只是对有符号数运算而言. 下面我们来看两个溢出的例子. 执行后将产生溢出. 因为add al, 99进行的有符号运算是: 而结果197超出了机器所能表示的8位符号数的范围:-128~127. 执行后,将产生溢出. 因为add al, 088h进行的有符号数运算是: 而结果-136超出了机器所能表示的8位有符号数的范围: -128~127. 如果在进行有符号数运算时发生溢出,那么运算的结果将不正确. 就上面的两个例子来说: 分析:add指令运算的结果是(al) = 05Ch, 因为进行的是有符号运算,所以al中存储的是有符号数,而5Ch是有符号数-59的补码. 如果我们用add指令进行的有有符号数运算,则98+99 = -59 这样的结果让人无法接受. 造成这种情况的原因,就是实际的结果197,作为一个有符号数,在8位寄存器al中存放不下. 同样,对于: 分析:add指令运算的结果是(al) = 78h,因为进行的是有符号数运算,所以在al中存储的是有符号数,而78h表示有符号数120. 如果我们用add指令进行的有符号数运算,则-16-120= 120 这样的结果显然不正确. 造成这种情况的原因,就是实际的结果-136,作为一个有符号数,在8位寄存器al中存放不下. 由于在进行有符号数运算时,可能发生溢出而造成结果的错误. 则CPU需要对指令执行后是否产生溢出进行记录. flag的第11位OF,溢出标志位. 一般情况下,OF记录了有符号数运算的结果是否发生出溢出. 如果发生溢出,OF = 1;如果没有,OF = 0. 一定要注意CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位. 比如: add指令执行后:CF = 0,OF = 1. 前面我们说过,CPU在执行add等指令时,就包含了两种含义:无符号数运算和有符号数运算. 对于无符号数运算,CPU用CF位来记录是否产生了进位;对于无符号数运算,CPU用OF位来记录是否产生了溢出,当然,还要用SF来记录结果的符号. 对于无符号运算,98+99没有进位,CF = 0;对于符号数运算,98+99发生溢出,OF = 1. add指令执行后:CF = 1,OF = 1. 对于无符号运算,0F0h+88h有进位,CF = 1;对于有符号数运算,0F0h+88h (-16+120)=104,不发生溢出,OF = 0. 我们可以看出,CF和OF所表示的进位和溢出,是分别对于无符号数和有符号数运算而言的,它们之间没有任何关系. 检测点2: 写出下面每条指令执行后,ZF、PF、SF、CF、OF等标志位的值. 答案如下:
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/52275.html