标志寄存器
x86架构CPU中,标志寄存器主要有3种作用:
- 存储相关指令执行后的结果,例如CF、PF、AF、ZF、OF标志位
- 执行相关指令时,提供行为依据,例如执行
JE
指令时会读取ZF的值,来决定是否进行跳转。 - 控制CPU的工作方式,例如IF、VM、TF等标志位
16位模式下,标志寄存器名称为FLAG,寄存器大小16位。
32位模式下,标志寄存器的名称为EFLAG,寄存器大小32位。
64位模式下,为RFLAG,寄存器大小64位。
EFLAG寄存器各个位的用途如下,其中灰色的部分为保留位。
在x86汇编语言中,读取FLAG寄存器的方式为:
通过汇编指令PUSHF将FLAG寄存器数据压入栈,然后通过POP将FLAG寄存器数据读入到通用寄存器,例如下面将FLAG寄存器内容写入AX寄存器
pushf
pop ax
如果需要写入FLAG寄存器,可通过POPF指令将栈顶数据送入FLAG寄存器。
CF标志位
CF标志位位于标志寄存器的第0位,在进行无符号数运算时,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。
例如两个16位数据0xFFFF和0x1000相加,会产生进位,这个进位值在16位寄存器中无法保存,为了解决这个问题,进位值会被保存到CF标志位中。
比如在16位汇编语言中:
mov ax, 0xFFFF
add ax, ax
执行完成后,AX寄存器的值为0xFFFE,CF标志位为1。
因为0xFFFF + 0xFFFF = 0x1FFFE,但是AX寄存器只有16位,所以将最高位1放置于CF标志位。
PF标志位
PF标志位位于标志寄存器的第2位,用途是记录指令执行后,其运算结果的所有位中1的个数是否为偶数:
当PF位为1时,表示1的个数为偶数
当PF位为0时,表示1的个数为奇数
例如:
mov al, 10
add al, 100
执行后,AL寄存器为01101110(二进制),其1的个数为5,所以PF位为0。
AF标志位
AF标志位位于标志寄存器的第4位,为辅助进位标志位,当执行一条运算指令后,如果第3位向第4位发生了进位,那么AF标志位为1,例如:
mov al, 0xF
add al, 1
此时AL寄存器为0x10,AF标志位为1。
ZF标志位
ZF标志位位于标志寄存器的第6位,用于记录相关指令执行后,其结果是否为0,如果结果为0,那么ZF标志位为1。
例如:
mov ax, 10
sub ax, 10
执行后,AX寄存器为0,ZF标志位为1。
SF标志位
SF标志位位于标志寄存器的第7位,用于记录相关指令执行后,其结果是否为负数(最高位为1表示负数),如果为负数,那么SF为1,如果不为负数,那么SF为0。
SF标志位是CPU对有符号数运算结果的一种记录,用于记录数据的正负,即最高位是否为1。
如果程序将其视为无符号数计算,那么SF标志位的值可以忽略。
例如:
mov al, 0
sub al, 1
此时,AL的值为11111111(-1),SF值为1。
TF标志位
TF标志位位于标志寄存器的第8位,名称为调试标志位,当TF值为1时,CPU每执行一条指令就会触发1号中断,典型案例就是MASM的Debug程序。
IF标志位
IF标志位位于标志寄存器第8位,表示是否响应中断。
如果IF为1,那么会响应所有类型的中断
如果IF为0,那么只响应不可屏蔽中断。
IF标志位的值可通过指令CLI设置为0,通过STI指令设置为1,这两个指令均没有操作数。
DF标志位
IF标志位位于标志寄存器第9位,名称为方向标志位,默认为0
当DF为1时,存储器地址自动减少,串操作指令为自动减量指令。
当DF为0时,存储器地址自动增加,串操作指令为自动增量指令。
可通过汇编指令CLD将DF标志位设置为0,也可通过STD将DF设置为1。
串操作指令包含MOVSB,MOVSW,MOVSD。
例如下面的案例,需要将DS:SI后面的100字节数据复制到ES:DI开始的内存区域:
mov cx, 100
cld
rep movsb
如果是将DS:SI前面的100字节数据复制到ES:DI前面的内存区域:
mov cx, 100
std
rep movsb
OF标志位
OF标志位位于标志寄存器的第9位,名称为溢出标志位。对于有符号数运算而言,如果计算后发生了溢出,那么OF标志位会设置为1。
例如:
mov al, 100
add al, 30
由于AL是8位寄存器,所以相加后会溢出(AL寄存器的值为-126,二进制表示为1000 0010),运算结果将不正确,此时OF标志位就会设置为1。
判断单个标志状态指令
这组指令单独判断5个状态标志之一,根据某一个标志是0或1决定是否跳转
指令 | 跳转逻辑 | 状态标志 | 值 |
---|---|---|---|
JE | 相等时跳转 | ZF, 零标志位置位1(1--即为0) | ZF = 1时,跳转 |
JNE | 不相等时跳转 | ZF, 零标志位置位0(0--即不为0) | ZF = 0时,跳转 |
JZ | 等于0时跳转 | ZF | ZF = 1时,跳转 |
JNZ | 不等于0时跳转 | ZF | ZF = 0时,跳转 |
JS | 为负跳转 | SF | SF=1时,跳转 |
JNS | 为正跳转 | SF | SF=0时,跳转 |
JO | 溢出跳转 | OF | OF=1时,跳转 |
JNO | 未溢出跳转 | OF | OF=0时,跳转 |
JP/JPE | 为偶跳转 | PF, 判断结果中“1”的个数是偶是奇 | PF=1时,跳转 |
JNP/JPO | 为奇跳转 | PF, 判断结果中“1”的个数是偶是奇 | PF=0时,跳转 |
JC | 进位/借位跳转 | CF,进位/ 借位标志 | CF=1时,跳转 |
JNC | 未进位/借位跳转 | CF,进位/ 借位标志 | CF=0时,跳转 |