汇编语言:标志寄存器ZF、PF、SF、CF、OF、DF、IF、AF

2024-08-23 00:44

本文主要是介绍汇编语言:标志寄存器ZF、PF、SF、CF、OF、DF、IF、AF,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        CPU内部的寄存器中,一种特殊的寄存器(对于不同的CPU,个数和结构可能都不同),具有以下3种作用。

(1)用来存储相关指令的某些执行结果

(2)用来为CPU执行相关指令提供行为依据

(3)用来控制CPU的相关工作方式

        这种特殊的寄存器在8086CPU中,被称为标志寄存器,8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(Program Status Word,PSW)。8086CPU的标志寄存器结构图如下:

其中,1、3、5、12、13、14、15位在8086CPU没有使用,不具有任何含义。

tips:

        在debug中,对标志位的表示按照显示顺序如下:

标志位值OFDFIFSFZFAFPFCF
0NVUPDIPLNZPONC
1OVDNEINGZRPECY

OF(Overflow Flag):溢出标志位,一般情况下,它记录了有符号运算的结果是否发生了溢出。

NV(No Overflow)= 0:没有溢出

OV(Overflow)= 1:溢出

DF(Direction Flag):方向标志位,在串行处理指令中,控制每次操作后si、di的增减。

df = UP = 0:每次操作后si、di递增,即:(si) = (si) + 1; (di) = (di) + 1;

df = DN(down)= 1:每次操作后si、di递减,即:(si) = (si) - 1; (di) = (di) - 1;

IF(Interrupt Flag):中断标志位。它用来控制8086是否允许接收外部中断请求。若IF=1,8086能响应外部中断,反之则屏蔽外部中断。
DI(Disabled Interrupt)= 0:不允许中断
EI (Enable Interrupt)= 1:允许中断

SF(Signed Flag):符号标志位,记录相关指令执行后,其结果是否为负,如果结果为负,则sf = 1,如果结果为非负,则sf = 0。

NG(Negative,负数)= 1:结果为负

PL(Plus,正数)= 0:结果为正

ZF(Zero Flag):零标志位,记录相关指令执行后,其结果是否为0,如果结果为0,则zf = 1,如果结果不为0,则zf = 0。

ZR(Zero)= 1:结果为0

NZ(Not Zero)= 0:结果不为0

AF(Auxiliary carray flag):辅助进位标志位,运算过程中看最后四位,不论长度为多少,最后四位向前有进位或者借位,AF = 1,否则AF = 0

AC(Auxiliary Carry)= 1:有辅助进位

NA(Not Auxiliary carry)= 0:没有辅助进位

PF(Parity Flag):奇偶标志位,记录相关指令执行后,其结果所有的位中 1 的个数是否为偶数,如果 1 的个数为偶数,则pf = 1,如果1的个数为奇数,则pf = 0。

PE(Parity Even,偶数)= 1:结果有偶数个1

PO(Parity Odd,奇数)= 0:结果有奇数个1

CF(Carry Flag):进位标志位,一般情况下,在进行无符号运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从最高位借位值。

CY(Carried Yes)= 1:有进位

NC(Not Carried)= 0:没进位

1. ZF 标志(Zero Flag)

        标志寄存器的第6位是 zf,零标志位,记录相关指令执行后,其结果是否为0,如果结果为0,则zf = 1,如果结果不为0,则zf = 0。

比如

mov ax, 1

sub ax, 1

指令执行后,结果为0,则zf = 1。

mov ax, 2

sub ax, 1

指令执行后,结果不为0,则zf = 0

tips:

        在8086指令集中,有的指令的执行是影响标志寄存器的,比如:add,sub,mul,div,and,or,inc,dec等,它们大都是运算指令(进行算术运算或逻辑运算);有的指令的执行是不影响标志寄存器的,比如:mov,push,pop等,它们大都是传送指令。我们在使用一条指令的时候,要注意这条指令的全部功能,包括执行结果对标志寄存器的哪些标志位会产生影响。

2. PF 标志(Parity Flag)

        标志寄存器的第2位是 pf,奇偶标志位,记录相关指令执行后,其结果所有的位中 1 的个数是否为偶数,如果 1 的个数为偶数,则pf = 1,如果1的个数为奇数,则pf = 0。

比如

mov ax, 1

sub ax, 1

指令执行后,结果为0,所有的位中 1 的个数为 0 (偶数)个,则pf = 1。

mov ax, 2

sub ax, 1

指令执行后,结果为1,所有的位中 1 的个数为 1 (奇数)个,则pf = 0

3. SF 标志(Signed Flag)

        标志寄存器的第7位是 sf,符号标志位,记录相关指令执行后,其结果是否为负,如果结果为负,则sf = 1,如果结果为非负,则sf = 0。

        计算机中,通常用补码来表示有符号数,在计算机中,一个数可以看作是有符号数,也可以看成无符号数。

比如

0000 0001B,可以看成无符号数 1,也可以看成有符号数 +1

1000 0001B,可以看成无符号数 129,也可以看成有符号数 -127(原码:对补码再做一次求补码操作得到一个用补码形式表示的数的原码,补码 = 反码 + 1,补码:1000 0001B ,原码 = 反码 + 1 = 1111 1110B + 1 = 1111 1111b = -127)。

        所以,对于同一个二进制数,计算机可以将它当作无符号数据来运算,也可以当作有符号数据来运算。

比如

mov al, 10000001b

add al, 1

结果为:10000010b

        可以将 add 指令进行的运算当作无符号数的运算,那么 add 指令相当于计算 129 + 1,结果 = 130 (1000 0010b);也可以将 add 指令进行的运算当作有符号数的运算,那么 add 指令相当于计算 -127 + 1,结果 = -126(1000 0010b)

        所以,SF标志,就是CPU对有符号运算结果的一种记录,它记录了数据的正负。在我们数据当作有符号数来运算的时候,可以通过它来得到结果的正负;如果我们将数据当作无符号来运算,SF 的值则没有意义,虽然相关指令影响了它的值。也就是说,CPU 在进行 add 等指令时,是必然会影响到 SF 标志的值的。至于我们需不需要这种影响,那就看我们如何看待指令所进行的运算了。

比如

mov al, 10000001b

add al, 1

指令执行后,结果为:10000010b,sf = 1,表示:如果指令进行的是有符号数运算,那么结果为负,如果指令进行的是无符号数运算,虽然 sf = 1,但没有意义。

比如

mov al, 10000001b

add al, 01111111b

指令执行后,结果为:0,sf = 0,表示:如果指令进行的是有符号数运算,那么结果为非负。

        有些指令的执行会影响标志寄存器中的多个标记位,比如:sub al, al,执行后,标志寄存器中的 zf = 1,pf = 1,sf = 0

检测点11.1

        写出下面每条指令执行后,ZF,PF,SF等标志的值

sub al, al        ZF = 1, PF = 1, SF = 0

mov al, 1        ZF = 1, PF = 1, SF = 0(传送指令不影响标志寄存器的状态)

push ax          ZF = 1, PF = 1, SF = 0(传送指令不影响标志寄存器的状态)

pop bx           ZF = 1, PF = 1, SF = 0(传送指令不影响标志寄存器的状态)

add al, bl       ZF = 0, PF = 0, SF = 0(结果 = 0000 0010b,不为0,奇数个1,符号位为0)

add al, 10      ZF = 0, PF = 1, SF = 0(结果 = 0000 1100b,不为0,偶数个1,符号位为0)

mul al            ZF = 0, PF = 1, SF = 0 (结果 ax = 0000 0000 1001 0000b, 不为0, 偶数个1, 两个相同的数相乘结果肯定为正数,所以SF = 0)

在debug中,

4. CF 标志(Carry Flag)

        标志寄存器的第0位是 cf,进位标志位,一般情况下,在进行无符号运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从最高位借位值。

        对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N-1位,就是它的最高位,而假想存在的第N位,就是相当于最高有效位的更高位,如下图所示。

        

我们知道,当两个数据相加时,有可能从最高有效位向更高位产生进位,8086CPU的标志寄存器的CF位就是来记录这个进位值的。

比如

mov al, 98h

add al, al        ;该指令执行后,(al) = 30h, CF = 1

add al, al        ;该指令执行后,(al) = 60h, CF = 0

而当两个数进行减法运算时,有可能向更高位借位,8086CPU的标志寄存器的CF位记录了这个借位值。

比如

mov al, 97h

sub al, 98h        ;该指令执行后,(al) = ffh, 向更高位借位了,CF = 1

sub al, al            ;该指令执行后,(al) = 0h, CF = 0

5. OF 标志(Overflow Flag)

        标志寄存器的第11位是 of,溢出标志位,一般情况下,它记录了有符号运算的结果是否发生了溢出。

        在进行有符号数运算时,如果超过了机器所能表示的范围称为溢出。比如,8位有符号数的范围:-128 ~ 127。16位有符号数的范围:-32768 ~ 32767。

示例:

8位有符号数

mov al, 100

add al, 29        ;该指令执行后,(al) = 01h,溢出了,OF = 1

示例:

8位有符号数

mov al, -100

sub al, 29        ;该指令执行后,(al) = 7fh,溢出了,OF = 1

tips:

-100 的补码:1001 1100b = 9ch

-29 的补码:1110 0011b = E3h

检测点11.2

        写出下面每条指令执行后,ZF、PF、SF、CF、OF 等标志位的值

sub al, al        ;ZF = 1,PF = 1,SF = 0,CF = 0,OF = 0(结果al = 0)

mov al, 10h    ;ZF = 1,PF = 1,SF = 0,CF = 0,OF = 0(传送指令,不影响标志寄存器的状态)

add al, 90h     ;ZF = 0,PF = 1,SF = 1,CF = 0,OF = 0(对于无符号数来说,0001 0000B + 1001 0000B = 1010 0000B,没有向更高位进位,所以 CF = 0,对于有符号数来说,0001 0000B + 1001 0000B = 1010 0000B = -96,实际上换成十进制是 16 + (-112) = - 96,没有溢出,所以 OF = 0,结果不为0,所以 ZF = 0,结果有2(偶数)个1,所以 PF = 1)

mov al, 80h     ;ZF = 0,PF = 1,SF = 1,CF = 0,OF = 0(传送指令,不影响标志寄存器的状态)

add al, 80h      ;ZF = 1,PF = 1,SF = 0,CF = 1,OF = 1(对于无符号来说,1000 0000B + 1000 0000B = 0000 0000B = 0,有向更高位进位,所以 CF = 1,对于有符号数,1000 0000B + 1000 0000B = 0000 0000B = 0,,实际上换成十进制是 -128 - 128 = -256,溢出了,所以,OF = 1,结果为0,所以 ZF = 1,结果有 0 (偶数)个1,所以 PF = 1,结果的符号位为0,所以 SF = 0)

mov al, 0FCh   ;ZF = 1,PF = 1,SF = 0,CF = 1,OF = 1(传送指令,不影响标志寄存器的状态)

add al, 05h       ;ZF = 0,PF = 0,SF = 0,CF = 1,OF = 0(对于无符号数来说,1111 1100B + 0000 0101B = 0000 0001B,有向更高位进位,所以 CF = 1,对于有符号数,1111 1100B + 0000 0101B = 10000 0001B = 0000 0001B = 1,实际上换成十进制是:-4 + 5 = 1,没有溢出,所以 OF = 0,结果为1,所以 ZF = 0,结果有1(奇数)个1,所以 PF = 0,结果的符号位为0,所以 SF = 0)

mov al, 7Dh      ;ZF = 0,PF = 0,SF = 0,CF = 1,OF = 0(传送指令,不影响标志寄存器的状态)

add al, 0Bh      ;ZF = 0, PF = 1,SF = 1,CF = 0,OF = 1(对于无符号数来说,0111 1101b + 0000 1011b = 1000 1000b,没向更高位进位,所以 CF = 0,对于有符号数来说,0111 1101b + 0000 1011b = 1000 1000b = -8,实际上换成十进制是 125 + 11 = 136,溢出了,所以 OF = 1,结果为 -8,所以 ZF = 0,结果有 2(偶数)个1,所以 PF = 1,结果的符号位为1,所以 SF = 1)

6. DF(Direction Flag)

        标志寄存器的第10位是 df,方向标志位,在串行处理指令中,控制每次操作后si、di的增减。

df = UP = 0:每次操作后si、di递增,即:(si) = (si) + 1; (di) = (di) + 1;

df = DN(down)= 1:每次操作后si、di递减,即:(si) = (si) - 1; (di) = (di) - 1;

注:本文是学习笔记

《汇编语言(第4版)》- 王爽

这篇关于汇编语言:标志寄存器ZF、PF、SF、CF、OF、DF、IF、AF的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1097866

相关文章

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像

cf 164 C 费用流

给你n个任务,k个机器,n个任务的起始时间,持续时间,完成任务的获利 每个机器可以完成任何一项任务,但是同一时刻只能完成一项任务,一旦某台机器在完成某项任务时,直到任务结束,这台机器都不能去做其他任务 最后问你当获利最大时,应该安排那些机器工作,即输出方案 具体建图方法: 新建源汇S T‘ 对任务按照起始时间s按升序排序 拆点: u 向 u'连一条边 容量为 1 费用为 -c,

CF 508C

点击打开链接 import java.util.Arrays;import java.util.Scanner;public class Main {public static void main(String [] args){new Solve().run() ;} }class Solve{int bit[] = new int[608] ;int l

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

AF透明模式/虚拟网线模式组网部署

透明模式组网 实验拓扑  防火墙基本配置 接口配置 eth1  eth3   放通策略  1. 内网用户上班时间(9:00-17:00)不允许看视频、玩游戏及网上购物,其余时 间访问互联网不受限制;(20 分) 应用控制策略   2. 互联网用户只允许访问内网两台服务器的 WEB、SSH 和远程桌面服务,其余 服务均不允许访问;(20 分) 外网访问内网的限制策略   虚拟网线模式组网 实

【CF】C. Glass Carving(二分 + 树状数组 + 优先队列 + 数组计数)

这题简直蛋疼死。。。。。 A了一下午 #include<cstdio>#include<queue>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int maxn = 200005;int h,w,n;int C1[maxn],C2[maxn];int

【CF】E. Anya and Cubes(双向DFS)

根据题意的话每次递归分3种情况 一共最多25个数,时间复杂度为3^25,太大了 我们可以分2次求解第一次求一半的结果,也就是25/2 = 12,记录结果 之后利用剩余的一半求结果 s-结果 = 之前记录过的结果 就可以 时间复杂度降低为 3 ^ (n/2+1) 题目链接:http://codeforces.com/contest/525/problem/E #include<set

【CF】D. Arthur and Walls(BFS + 贪心)

D题 解题思路就是每次检查2X2的方格里是否只有一个‘*’,如果有的话这个*就需要变成‘.’,利用BFS进行遍历,入队的要求是这个点为. 一开始将所有的'.'全部加入队列,如果碰到一个'*'变成'.'就入队,判断的时候从4个方向就行判断 题目链接:http://codeforces.com/contest/525/problem/D #include<cstdio>#include<

寄存器B

MCS-51单片机的中央处理器包含运算部件和控制部件两部分。         1. 运算部件         运算部件以算术逻辑运算单元ALU为核心,包含累加器ACC、B寄存器、暂存器、标志寄存器PSW等许多部件,它能实现算术运算、逻辑运算、位运算、数据传输等处理。         算术逻辑运算单元ALU是一个8位的运算器,它不仅可以完成8位二进制数据加、减、乘、除等基本的算

COCO Kepoints 标志位

COCO 数据集中annotations字段keypoints是一个长度为3*k的数组,其中k是category中keypoints的总数量。每一个keypoint是一个长度为3的数组,第一和第二个元素分别是x和y坐标值,第三个元素是个标志位v,v为0时表示这个关键点没有标注(这种情况下x=y=v=0),v为1时表示这个关键点标注了但是不可见(被遮挡了),v为2时表示这个关键点标注了同时也可见