x86标志寄存器

一下内容来自:
flags部分
flags部分

参考书:《x86汇编语言:从实模式到保护模式》

FLAGS

运算结果标志位

FLAGS寄存器是cpu8086处理器中的一种标志寄存器,和我们常见的其他寄存器相比有如下特点

  1. 每一个标志寄存器的大小都只有一个字节,(基本无法存储任何数据,除了0和1)
  2. 其内容会收到cpu运行的指令的影响,在特定指令运行后,有一个或几个flag的值更具运行结果发生改变
  3. 会对一些条件判断指令产生影响

FLAGS寄存器的格式如下
在这里插入图片描述
其实,这16位本身是一个寄存器名为FLAGS但是,由于flag和flag之间的功能相互隔离,基本可以看成独立,因此,这将其分开。但这16位本身为一体。
FLAGS寄存器中的十六位中只有0、2、4、6、7、8、9、10、11,这9位有实际意义,其他由系统保留(当然这和我们没有关系,我们基本不会直接对FlAGS寄存器的内容进行更改)

CF(进位标志)

FLAGS的0位是CF,进位标志位
当无符号数在运算中发生进位,或者向前借位时,cpu将其置1。

  1. 0x0f + 0x01=0x10,这时就发生了进位,CF被置1。
  2. 在减法中0x10-0x01=0xE,这里就发生借位(这里使用的是十六进制)

虽然加法和减法中一个看的是进位,一个看的是借位,但其实两者是一个道理,记录的都是进位。
我们不妨把减法看成一个正数加上一个负数,并换算成补码。0x01的补码是0xff,这个数加上0x10必定会发生进位,因此,CF置1。
这也解释了为什么,CF叫进位标志而不是借位标志。其实减法本质上也可以看成加法

PF(奇偶标志)

FLAGS的2位是PF,奇偶标志位。
PF的主要职责就是判断,指令执行的结果的所有位数中1的个数是奇数还是偶数,如果是偶数,置1,如果是奇数,置0。
这里的结果主要包括:加、减、乘、除运算,和逻辑运算等。规则如下

mov ax, 0x1
add ax, 0x10 ;ax 0x11, PF=1

AF(调整标志位)

FLAGS的第4位是AF标志位,调整标志位。
其主要作用是判断低半字节有没有向高半字节进位或者借位,如果有AF=1,否则AF=0。

低半字节和高半字节:
我们进行数据计算时,表示一个数的位数都是有限的,如ax寄存器位16位,而这16位又可以分为高8位和低八位,这里的高8位就是高半字节,低8位就是低半字节。

当我们用ax寄存器进行运算时,如果低8位向高8位有进位或借位的情况,AF=1,否则AF=0

ZF(零标志位)

FLAGS第6位是ZF,称为零标志位。
顾名思义,ZF标志位的作用就是判断运算结果是否为0,如果为0,ZF=1,否则ZF=0。
如下

mov al, 0x1
sub al, 0x1

al=0,zf=1
结果可以来自:加减乘除,和逻辑运算。也包括CMP运算。

SF(符号标志位)

SF,判断指令执行的结果是否为,如果为负,SF=1,否则SF=0。
例如:

mov al, 0xF1
add al, 0x1

这里al的结果是0xF2,换算成二进制11110010b,-14,SF=1

这看起来“好像”是,当结果为负时,SF置1,但如果我们把这个运算看成是无符号原算时会怎么样?
这时al的结果是,242,但这时SF还是置1,这看起来好像是个问题?

在指令执行过程中,CPU是无法判断一个数是正数还是负数的,它所能判断的只有,结果的最高位是否为1,如果为1无论是有符号运算还是无符号运算,SF都会置1。

所以,最终的结果就是,当我们把运算看成有符号运算时SF有意义,而当成无符号运算时SF没有意义

当然,如果说一定要把两者区分,那我们该怎么做呢,我的答案是,没有必要,因为在进行无符号原算时,SF根本用不到,只有在进行有符号运算时,SF才可能会用到。

OF溢出标志位

顾名思义,OF标志位判断的就是,运算结果是否溢出。如果溢出OF=1,否则OF=0。
OF的判断公式为:OF=Cn 异或 Cn-1
Cn:最高有效位进位
Cn-1:此稿有效位进位

如何定义溢出

mov al, 0x70
add al,al

从二进制的角度来看,01110000 + 01110000 = 11100000,两个整数相加,变成了一个负数,这就是溢出。
最高有效位没有进位,即Cn=0,而次高有效位进位,即Cn-1=1,因此,CF=1。

这里CPU用于判断,有符号运算的结果是否溢出的方法非常巧妙。不止两正数相加为负的情况,两负数相加为正的情况也同样可以判断出来。
如:

mov al, 0x90
add al, al

10010000+10010000=0010 0000,两个负数计算后变成了一个正数,溢出
Cn=1,Cn-1=0,CF=0,和实际情况完美对应。

mov al, 1h
sub al, 1h

状态控制标志位

TF(跟踪标志位)

flag的第8位是TF,跟踪标志位用于标识CPU是否允许单步中断,以进行程序调试。TF=0时,8086CPU处于正常状态;TF=1时,8086CPU处于单步状态,每执行一条指令就自动产生一次单步中断。

8086的debug功能依赖于8086CPU的单步调试功能。

IF(中断允许标志位)

flags的第9位是IF,中断允许标志位
IF置为0,禁止其他的可屏蔽中断;如果允许处理可屏蔽中断,则将IF置为1。

这是一个可以有用户控制的标志位,控制指令没有操作数

STI			;将IF设置为1,允许可屏蔽中断。
CLI			;将IF设置为0,禁止可屏蔽中断。

DF(方向标志位)

flags的第10为,是方向标志位。可以控制数据读取的方向
这个标志位主要用于配合movsb,movsw,进行批量数据传输。

和IF标志位一样,其值可以由用户控制

cld		;OF置0,进行正向传递,从低地址向高地址读
std		;OF置1,进行反向传递,从高地址向低地址读

使用方式如下

  ;显示Label Offset:
  cld
  mov si, mytext 	;ds:di,起始地址
  mov di, 0			;es:di,目标地址
  mov cx, 13 		;循环的次数
  rep movsw 		;movsw和movsb指令会自动使用es作为目的数据段,不用可以拼接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值