标志寄存器
标志寄存器概述
在计算机中,有一个专用16位的寄存器FLAGS(标识寄存器)。
标志寄存器是按位起作用的,每一位都有专门的含义,记录特定的信息。
标志寄存器标志位的作用:
存储相关指令的某些执行结果
为CPU执行相关指令提供行为依据
控制CPU的相关工作方式
FLAGS寄存器结构:
与其他寄存器不同,FLAGS寄存器的位数是从右往左的
位数 | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
用途 | ----- | ----- | ----- | OF溢出 | DF方向 | IF中断 | TF | SF符号 | ZF零 | ----- | AF辅助进位 | ----- | PF奇偶 | ----- | CF进位 |
判断 | ----- | ----- | ----- | 是/否 | 减量/增量 | 允许/关闭 | ----- | 负/正 | 是/否 | ----- | 是/否 | ----- | 偶/奇 | ----- | 是/否 |
true | ----- | ----- | ----- | OV | DN | EI | ----- | NG | ZR | ----- | AC | ----- | PE | ----- | CY |
false | ----- | ----- | ----- | NV | UP | DI | ----- | PL | NZ | ----- | NA | ----- | PO | ----- | NC |
对应控制面板的该位置
负数存储过程(划到最后面看)
相关指令
ADC 指令
作用:在计算加法的时候,一同带上CF标志位的进位值进行计算。
常见的寄存器最多只有16位,进行加乘的结果一般不能超过0FFFFH这个上限,当需要计算的值超过16位时比如当进行1AFFFF+2CFFFC这个操作时,则需要结合ADC和ADD这两个指令求出结果
具体详见代码。
SBB指令
作用:在计算减法的时候,一同带上CF标志位上的借位值进行计算。
计算00370000h-00300001H的过程,需要结合SUB和SBB这两个指令求入结果,详情看代码。
assume cs:code,ds:data,ss:stack
data segment
DW 256 DUP(0H)
data ends
stack segment
DW 256 DUP(0H)
stack ends
code segment
start:
mov ax,0037h
mov bx,0000h
mov cx,0030h
mov dx,0001h
sub bx,dx
sbb ax,cx
mov ax,4c00H
int 21H
code ends
end start
CMP比较指令
计算减法功能,但不保存结果,根据计算结果影响标志寄存器的位
如:CMP AX,BX
这一操作会进行AX-BX,但是不保存结果,而是用结果去影响标志寄存器的位
CMP指令比较对照(CMP A,B)
影响结果 | 对比内容 | 备注 |
---|---|---|
ZF=1 | A=B(等于) | A-B=0 |
ZF=0 | A!=B(不等于) | |
CF=1 | A<B(小于) | A-B<0 |
CF=0 | A>=B(大于或等于) | |
CF=0 并且 ZF=0 | A>=B(大于) | |
CF=1 或者 ZF=1 | A<=B(小于或等于) |
条件转移指令
根据条件是否满足,来决定是否修改IP
脚尖转移指令对照(CMP A,B)
判断内容 | 判断条件 | 条件转移指令 |
---|---|---|
ZF=1 | A=B(等于) | JE |
ZF=0 | A!=B(不等于) | JNE |
CF=1 | A<B(小于) | JB |
CF=0 | A>=B(大于或等于) | JNB |
CF=0 并且 ZF=0 | A>=B(大于) | JA |
CF=1 或者 ZF=1 | A<=B(小于或等于) | JNA |
CLD指令
将标志寄存器的DF位置0(将DF的值改变为0)
STD指令
将标志寄存器的DF位置1
串传送指令
MOVSB指令
将DS:SI指向的内存单元中的字节传送入ES:DI指向的内存单元,然后根据DF标志位的值,将SI、DI递增或递减
MOVSW指令
将DS:SI指向的内存单元中的字传送入ES:DI指向的内存单元,然后根据DF标志位的值,将SI、DI递增2或递减2
REP指令
重复前缀指令,根据cx的值,重复执行后面的串传送指令
详情见代码(结果与上文串传送结果一致):
assume cs:code,ds:data,ss:stack
data segment
db 'miss you'
db 8 DUP(0H)
data ends
stack segment
DW 256 DUP(0H)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0h
mov es,ax
mov di,08h
cld
mov cx,4H
rep movsw
mov ax,4c00H
int 21H
code ends
end start
标志寄存器的栈指令
pushf指令,将FLAGS寄存器16位数据的值入栈
popf指令,出栈16位数据到FLAGS寄存器中
assume cs:code,ds:data,ss:stack
data segment
DW 256 DUP(0H)
data ends
stack segment
DW 256 DUP(0H)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
cmp sp,60h
mov ax,1234h
push ax
pushf
mov ax,4c00H
int 21H
code ends
end start
ZF标志寄存器
处于FLAGS寄存器的第6位上,是零标志位,负责记录相关指令执行后,其结果是否为0,如果true,则ZF的值为1,显示为ZR,如果false,则ZF的值为0,显示NZ。
位数 | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
存储 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
显示 | ----- | ----- | ----- | NV | UP | DI | ----- | PL | ZR | ----- | NA | ----- | PO | ----- | NC |
注意:在以算计指令中,有的指令执行影响标志寄存器,有的不影响
如:ADD、SUB、INC 、DEC 、MUL 、DIV等指令
的执行都会影响标志寄存器
而:MOV等指令执行则不会影响标志寄存器
PF标志寄存器
处于FLAGS寄存器的第2位上,是奇偶标志位,负责记录相关指令执行后,其结果低8位中1的个数为偶数PF值为1,显示PE;如果为奇数,PF值为0,显示PO;
如:
SF标志寄存器
- 学习此寄存器前,请先了解负数存储过程及其相关反码、补码概念
- 处于FLAGS寄存器的第7位上,是符号标志位,负责记录相关指令执行后,其结果为负,SF值为1,显示NG;结果为非负,SF值为0,显示PL;
对于同一个二进制数
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
当其表示为无符号数字类型时:对应的十进制数为:129
当其表示为有符号数字类型时:对应的十进制数为:-127
无符号数字类型不能存储负数,但是相对存储的非负数的范围更广;
有符号数字类型可以存储负数,但是相对存储的非负数的范围更小。
SF标志寄存器对有符号数字类型和无符号数字类型都起作用,但是对无符号数字类型无意义。
CF标志寄存器
处于FLAGS寄存器的第0位上,是进位标志位,负责记录相关指令执行后,其运算结果的最高有效位向更高位的进位值,或从更高位的借位值
SF标志位更关注有符号数据,而CF标志位更关注无符号数据
下列计算均以无符号数据为参考数据
当两个8位的二进制数
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
和
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
---|
相加时,最高位相加会向更高一位进位,得到一个16位的二进制数
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
此时即是进位,CF位存储的值为1,显示CY
当两个8位的二进制数
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
减去
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
---|
此时会向更高位借位,得到一个8位的二进制数
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
---|
此时即是借位,CF位存储的值为1,显示CY
但如果是
两个8位的二进制数
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
和
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
---|
相加时,最高位相加会向更高一位进位,得到一个8位的二进制数
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
则CF位存储的值为0,显示NC
OF标志寄存器
处于FLAGS寄存器的第11位上,是溢出标志位,负责记录有符号数运算的结果是否发生了溢出,如果发生了溢出,OF存储的值为1,显示OV;如果没有发生溢出,OF存储的值为0,显示NV.
对于无符号数而言,运算结果超出了原寄存器的存储范围,称为进位,
对于有符号数而言,运算结果超出了原寄存器的存储范围,称为溢出。
8位有符号数的存储范围是:-128~127
8位无符号数的存储范围是:0~255
DF寄存器
处于FLAGS寄存器的第10位上,是方向标志位,在串处理指令中,它控制每次操作后SI、DI的增减变化。
当DF = 0 时,每次操作后SI、DI递增。
当DF = 1 时,每次操作后SI、DI递减。