标志寄存器的三种作用:
(1)用来存储相关指令的某种执行结果;
(2)用来为CPU执行相关命令提供行为依据;
(3)用来控制CPU的相关工作方式
8086寄存器也是有16位,但是与其他寄存器不同的是:其他寄存器是用来存放数据的,是整个寄存器具有一个含义。而标志寄存器是按位起作用的,他的每一位都有专门的含义,记录特定的信息。
8086cpu的寄存器的结构如图:
![](https://i-blog.csdnimg.cn/blog_migrate/af1cc9f88ddafdbf33f31ef3dac4dad4.png)
其中没有显示内容的就是没有使用的,有内容的都是有特殊的含义。
11.1 ZF标志————zero flag:结果=0第五个标志为ZR !=0为NZ
flag(标志寄存器)的第6位放的是ZF,他记录相关指令执行后其结果是否位0.结果为0,zf=1,结果不为0,zf=0。
![](https://i-blog.csdnimg.cn/blog_migrate/af1cc9f88ddafdbf33f31ef3dac4dad4.png)
可以在debug中调试运行下。
发现结果=0的时候flag寄存器的第5个标志是ZR
!=0时是NZ
![](https://i-blog.csdnimg.cn/blog_migrate/7fdad805a38b63e54c0aa7b3c0bbb81e.png)
要注意的是,只有运算指令才能改变flag寄存器
像add、sub、mul、div、inc、or、and等都可以改变他们大多是运算指令(进行逻辑或算数运算);
但是像mov、push、pop等就不会改变了。他们大多数是传送指令。
11.2 PF标志———Parity Flag :PE(偶数)、PO(奇数)
flag的第二位是PF标志,奇偶标志位。他记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数。如果1的个数是偶数,pf=1,如果为奇数,pf=0
![](https://i-blog.csdnimg.cn/blog_migrate/af1cc9f88ddafdbf33f31ef3dac4dad4.png)
16进制的6用二进制表示是0110,其中有两个1为偶数
16进制的1用二进制表示是1所以结果应该是0,非偶数
![](https://i-blog.csdnimg.cn/blog_migrate/ea9e76636853f9e4c5f88328c6bcc8dc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/650839411c88d118ae19d8a53ac5ee4f.png)
debug验证:
倒数第二个标志
mov 不改变flag的内容
执行 add ax,6后
倒数第二个标志PO(奇数)变成PE(偶数)
执行sub ax,5后 PE(偶数)又变成PO(奇数)
![](https://i-blog.csdnimg.cn/blog_migrate/eb158942948aebf14a76c327df789e57.png)
11.3 SF(Sign Flag)标志————符号标志位:负数为1(NG)非负数为0(PL)
计算机中的数据根据符分有两种类型:有符号数和无符号数
同一个二进制数据,计算机可以将它当作无符号数据来运算也可以当作有数据符号运算
不管我们如何看待,CUP在执行数据的时候就已经有两种结果了,而SF标志,就是对符号数运算结果的一种记录,记录数据的正负。
在我们将数据当作有符号的时候,SF记录他的正负,可以通过SF来得知结果的正负,当作无符号时SF没有意义,虽然他的值改变了。
就是,CPU执行add等指令时一定会影响SF的值,至于我们需不需要这个值,就要看我们自己了。
做一下课本上的例子
assume cs:code,ds:data,ss:stack
data segment
db 128 dup(0)
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
mov al,10000001b
add al,1
mov al,10000001b
add al,01111111b
mov ax,4C00h
int 21h
code ends
end start
add al,1后第四个标志从PL(正数0)变成NG 负数1)
意思就是如果进行有符号的运算,结果为负数
add al,7f后,第四个标志从NG(负数1)变成PL(正数0)
意思就是如果进行有符号运算的话结果为非负数
![](https://i-blog.csdnimg.cn/blog_migrate/b95774d1b8ee0a7e56fb01c2c6fee13f.png)
11.4 CF标志(进位标志位)——
运算过程中,al和ah是相互独立的。也就是说al运算时进位不会进到ah中,而是将数据保存在CF标志寄存器中,有进位标志寄存器为真(1)无进位为假(0)
还有借位也可以保存在CF中
mov al,98h
add al,al ;执行后al=30h,cf=1,记录了从最高位有效位向更高位的进位值
add al,al ;执行后al=60h,cf=0,记录了从最高位有效位向更高位的进位值
mov al,97h
sub al,98 ;执行后:al=ffh ,cf=1,cf记录了向更高位的借位值
sub al,al ;执行后:al=0h ,cf=0,cf记录了向更高位的借位值
![](https://i-blog.csdnimg.cn/blog_migrate/10707f97627f51f6fbc461fca873660b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4ec054a630b6919b727db37d8004bf41.png)
11.5 OF标志
计算机中每个寄存器或内存单元所能保存的数据都是有范围的,8位(八个0或者1)范围是00000000~11111111无符号0~255
有符号: -128~127
下面这张图片来自浙大翁恺老师的课件:
![](https://i-blog.csdnimg.cn/blog_migrate/4c60480680b80a6acb0c854dad860451.png)
为什么两边不相等?因为中间还有一个0
一共有256个数0~255(无符号)
有符号的话
如果两边都是128
128+128=256
但是中间还有一个0呀
128+128+1=257>256 越界啦
肯定不行,所以
要有一边少一边多,翁老师说根据补码的设计是左边多具体为什么我还不太清楚!!!!!!
既然数据是由范围的,那么如果溢出会怎样
会循环
一下图片来自浙大翁恺老师课堂
我们将这个范围看作一个圆圈,可以看到有两个分界点,一个是-128|127
另一个是-1|0
最小值是-128
当-128减去一个大于0的数,那么就会跑到127的地盘里
同理最大数是127,如果127加上一个大于零的数,就会跑到-128的地盘里
这样结果肯定是不对的
![](https://i-blog.csdnimg.cn/blog_migrate/72d8025820e7bbde1a338688be5c180f.png)
通过上边的分析我们知道了溢出
而CPU不能做一个什么都不知道的家伙,所以开发者便给它设计了OF标志寄存器,有溢出为真,没有则为假,
要注意区分的是OF、和CF
CF:无符号、进位
OF:有符号、溢出