本章的内容相对简单,但需要学习的知识点很多,也需要我们耐心去学习和理解一些细节内容。
不过,既然是做读书笔记,那只需要记录一下重点需要理解和记忆的内容,有些知识点原书上就有,可以一笔带过。
标志寄存器,说的是一种特殊的寄存器,它可以实现的功能是:
1、用来存储相关指令的某些执行结果。
2、用来为CPU执行相关指令提供行为依据。
3、用来控制CPU的相关工作方式。
这种寄存器称为“标志寄存器”,其中存储的信息通常被称为程序状态字(PSW)。而PSW,也就是Program status word的缩写。
但王爽老师的书中,有很多看似不太重要、但对理解和记忆有帮助的信息却没有讲出来。
比如这个“标志寄存器”,英文名叫作Flags Register,而其存储的信息称为PSW,但这一点却没有介绍清楚,往往导致初学者误认为“标志寄存器”就是PSW。
在8086CPU中标志寄存器有16位,其结构如下图所示:

从右到左,标志寄存器(FLAG)的第0、2、4、6、7、8、9、10、11位具有特殊的含义,一共9个标志位。
在本章,一共介绍了CF、PF、ZF、SF、OF、DF 6个标志位的具体用法,并且介绍了与之相关的adc、sbb、cmp,以及串传送指令(movsb、movsw)、pushf、popf等指令。
而在本章中,其实还有一些知识点没有介绍(可参考《汇编语言:基于x86处理器》基普 · 欧文著),那就是:
标志寄存器的标志分为两种类型:
1、控制标志(Control Flag):用于控制CPU的操作,例如,它们能使得CPU每执行一条指令后进入中断;在侦测到算术运算溢出时中断执行;进入虚拟8086模式,以及进入保护模式。
控制标志是:DF(方向标志位)、IF(中断标志位)、TF(追踪标志位)。
1)DF:全称Direction Flag,用于控制字符串操作指令中地址指针的增减方向。也是本章重点介绍的内容之一。
2)IF:全称Interrupt-enable Flag,用于决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。当IF=1时,CPU响应CPU外部的可屏蔽中断发出的中断请求;当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。
3)TF:全称Trap Flag,TF被置为1时,CPU会进入单步执行方式,即每执行一条指令,都会产生一个单步中断请求。这种方式主要用于程序的调试。
2、状态标志(Status Flag):反映了CPU执行算术和逻辑操作的结果。
状态标志包括CF、PF、ZF、SF、OF、AF。
而本章没有提到的AF标志:全称是Auxiliary Carry Flag,也就是辅助进位标志,它主要用于反映无符号数操作中低四位(bit 3)之间的进位或借位,在BCD编码中用得较多。有时候,AF在一些书中也被称为AC。
本章中,只重点介绍了CF、PF、ZF、SF、OF状态标志。
但实话说,王爽老师的这种“知识屏蔽”写书方式,有时候太缺乏统一性和连贯性,在有些基本概念都没介绍清楚的情况下就开始讲解,很容易造成理解上的困难。在此作一些笔记上的补充,算是弥补这种遗憾。
在8086CPU的指令集中,有的指令执行是影响标志寄存器的,比如:add、sub、mul、div、inc、or、and 等。
有些指令对标志寄存器没有影响,比如:mov、push、pop等。
一、ZF标志(zero flag)
ZF位于FLAG寄存器第6位,英文全称是zero flag。它记录相关指令执行后,如果结果为0,那么ZF=1;如果结果不为0,那么ZF=0。
例如:
mov ax,1
and ax,0
执行后,结果为0,则ZF=1,表示结果为0。以此类推。
二、PF标志(parity flag)
PF位于FLAG寄存器第2位,英文全称是parity flag。parity的就是“奇偶校验”的意思,从字面意义上讲,是在相关指令执行后,CPU将判断其结果的所有bit位中1的个数是否为偶数。如果1的个数为偶数,PF=1;如果为奇数,那么PF=0。
例如:
mov al,1
add al,10
执行后,结果为00001011B,其中1的个数为3个(奇数),则PF=0。以此类推。
三、SF标志(sign flag)
SF位于FLAG寄存器第7位,英文全称是sign flag,也就是符号标志的意思,以此判断数据是有符号,还是无符号的。
对于二进制数据,计算机既可以将它当作无符号的数据来运算,也可以当作有符号的数据来运算,比如:
00000001B,可以看作无符号数1,也可以看作有符号数+1
10000001B,可以看作无符号数129,也可以看作有符号数-127
为什么10000001B可以看作有符号数-127呢?这就涉及计算机补码的知识。
计算机中的整数数据分成有符号数和无符号数。无符号数是用所有的数据位表示数值,有符号数则是用最高位表示数据的正负性,其余位表示数值。
对于八位数无符号数,所有8位均是数据位,编码 00000000~11111111 表示0~255。
而八位有符号数,从右到左其最高位代表符号,其他7位表示数据。最高位的符号位是0代表正数,是1代表负数。
比如有符号数0111 1111,其最高位为0,代表正数,低 7位 111 1111就是这个正数的编码,也就是+127。
又比如有符号数1111 1111,其最高位为1 ,代表负数,低 7位111 1111 表示数值+ 127,而最高位和低7位联合起来,1111 1111 表示-1。
为什么1111 1111 表示-1,而不是-127呢?
因为每一个代表正数的二进制数据,按位取反后加1后得到的二进制数据,也就是补码,代表这个正数相对应的负数。
比如有符号数0111 1111(+127),按位取反后加1后(即补码),就是1000 0001,这个二进制数据才代表-127
而对于有符号数1111 1111来说,虽然低 7位111 1111 表示数值 +127,但最高位和低7位联合起来的1111 1111却是+1(0000 0001)按位取反后加1后(即补码)得来的结果。这个补码1111 1111,因其最高位为1,代表负数。所以1111 1111表示-1,而不是-127。
CPU在计算的过程中,当最高位为0时,SF=0(比如01111111),当最高位为1时,SF=1(比如10000001)
以上的表述,是不是觉得很绕?但只要记住以下两点就不必烧脑。对于有符号的十进制数,转化为二进制数的方式是:
1、如果是正数,保持十进制数不变,直接转化为二进制数。也就是说,正数的补码和原码相同。
2、如果是负数,首先将十进制的负数采取绝对值操作,转化为正数,然后转化为二进制数;接下来,将这个二进制数,按位取反加1,就得到了负数的二进制数。这个二进制数,就是负数的补码。
需注意的是:
1、如果将数据当作无符号数来运算,SF的值无意义。
2、如果指令进行的是有符号数运算,如果SF=1,那么结果为负。
3、如果指令进行的是有符号数运算,如果SF=0,那么结果为非

最低0.47元/天 解锁文章
509

被折叠的 条评论
为什么被折叠?



