特殊的寄存器(不同的处理机,个数和结构可能不同)
作用:
用来存储相关指令的某些执行结果
用来为
CPU执行相关指令提供行为依据用来控制
CPU的相关工作方式
8086CPU的标志寄存器(flag)有16位,其中存储的信息通常被称为程序状态字(PSW)

flag的1、3、5、12、13、14、15位在8086CPU中没有使用,不具有任何含义
flag的0、2、4、6、7、8、9、10、11位都具有特殊的含义
ZF标志
flag的第6位
零标志位
用于记录相关指令执行后,其结果是否为0。
若结果为0,则ZF=1
若结果不为0,则ZF=0
在8086CPU指令集中,有的指令的执行是影响标志寄存器的,如add、sub、mul、div、inc、or、and等运算指令(逻辑或算数运算);有的指令的执行对标志寄存器没有影响,如mov、push、pop等传送指令
PF指令
flag的第2位
奇偶标志位
用于记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数
若1的个数为偶数,则PF=1
若1的个数为奇数,则PF=0
SF标志
flag的第7位
符号标志位
用于记录相关指令执行后,其结果是否为负
若结果为负,SF=1
若结果不为负,SF=0
计算机中通常用补码来表示有符号数据
计算机中的一个数据可以看作是有符号数,也可以看作是无符号数
SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负。当数据当作有符号数来运算的时候,可通过SF来得知结果的正负;当数据当作无符号数来运算的时候,SF的值则无意义,虽然相关的指令影响了它的值
CF标志
flag的第0位
进位标志位
在进行无符号数运算时,用于记录运算结果的最高有效位向更高位的进位值,或从更高位的借位值
对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N-1位,就是它的最高有效位,而假想存在的第N位,就是相对于最高有效位的更高位

8086CPU使用flag的CF位来记录进位值与借位值
OF标志
溢出
当进行有符号数运算的时候,如果结果超过了机器所能表示的范围称为溢出
比如指令运算的结果用8位寄存器或内存单元来存放,那机器所能表示的范围就是-128–127,16位有符号数据,机器所能表示的范围是-32768–32767
由于在进行有符号数运算时,可能发生溢出而造成结果的错误,则CPU需要对指令执行后是否产生溢出进行记录
OF标志
flag的第11位
溢出标志位
用于记录有符号数运算的结果是否发生了溢出
若发生溢出,OF=1
若未发生溢出,OF=0
CF是对无符号数运算有意义的标志位
OF是对有符号数运算有意义的标志位
CF与OF之间无任何关系
adc指令
带进位的加法指令,利用CF位上记录的进位值
指令格式:adc 操作对象1,操作对象2
功能:操作对象1=操作对象1+操作对象2+CF
例:
-
1
2
3
4mov ax,2
mov bx,1
sub bx,ax ;(bx)=(bx)-(ax)=1-2=-1 CF=1
adc ax,1 ;(ax)=(ax)+1+CF=2+1+1=4
-
1
2
3mov al,98H
add al,al ;(al)=(al)+(al)=98H+98H=130H al中最高位1丢弃,CF=1
adc al,3 ;(al)=(al)+3+CF=30H+3+1=34H
在执行abc指令的时候加上CF的值的含义,是由abc指令前面的指令决定的。如果CF的值是被sub指令设置的,那么CF的含义为借位值;如果CF的值是被add指令设置的,那么CF的含义为进位值
加法分为两步进行:
低位相加
高位相加再加上低位相加产生的进位值
CPU提供adc指令的目的,就是来进行加法的第二步运算的
adc指令和add指令相配合就可以对更大的数据进行加法运算
编程
计算1EF0001000H+2010001EF0H,结果放在ax(高16位)和bx(次低16位),cx(低16位)中
计算分3步:
先将低16位相加,完成后,
CF中记录本次相加的进位值再将次高16位和
CF(来自低16位的进位值)相加,完成后,CF中记录本次相加的进位值最后高16位和
CF(来自次高16位的进位值)相加,完成后,CF中记录本次相加的进位值
1 | mov ax,001EH |
编写子程序
对两个128位数据进行相加
名称:add128
功能:两个128位数据进行相加
参数:ds:si指向存储第一个数的内存单元,128位的数据,需要8个字单元存储,由低地址单元到高地址单元一次存放128位数据由低到高的各个字,运算结果存储在第一个数的存储空间中。ds:di指向存储第二个数的内存空间
1 | add128: push ax |
sbb指令
带借位的减法指令,利用CF位上记录的借位值
指令格式:sbb 操作对象1,操作对象2
功能:操作对象1=操作对象1-操作对象2-CF
sbb指令执行后,将对CF进行设置
利用sub指令和sbb指令可以对任意大的数据进行减法运算
cmp指令
比较指令
功能相当于减法指令,只是不保存结果
指令格式:cmp 操作对象1,操作对象2
功能:计算操作对象1-操作对象2,但并不保存结果,仅仅根据计算结果对标志寄存器进行设置
无符号数比较
cmp ax,bx
若(ax)=(bx),则(ax)-(bx)=0,所以:ZF=1(零标志位)
若(ax)≠(bx),则(ax)-(bx)≠0,所以:ZF=0(零标志位)
若(ax)<(bx),则(ax)-(bx)将产生借位,所以:CF=1(进位标志位)
若(ax)≥(bx),则(ax)-(bx)不必借位,所以:CF=0(进位标志位)
若(ax)>(bx),则(ax)-(bx)既不必借位,结果又不为0,所以:CF=0(进位标志位)且ZF=0(零标志位)
若(ax)≤(bx),则(ax)-(bx)既可能借位,结果可能为0,所以:CF=1(进位标志位)且ZF=1(零标志位)
有符号数比较
cmp ah,bh
若(ah)=(bh),则(ah)-(bh)=0,所以:ZF=1(零标志位)
若(ah)≠(bh),则(ah)-(bh)≠0,所以:ZF=0(零标志位)
对于判断其他情况,并不能通过单纯的考查SF(符号标志位)来判断,必须结合查看OF(溢出标志位)来进行判断
若SF=1,OF=0,则(ah)<(bh)
若SF=1,OF=1,则(ah)>(bh)
若SF=0,OF=1,则(ah)<(bh)
若SF=0,OF=0,则(ah)≥(bh)
检测比较结果的条件转移指令
所有条件转移指令的转移位移都是-128–127
因cmp指令可以同时进行无符号数和有符号数的比较,则根据cmp指令的比较结果进行转移的指令也分为根据无符号数的比较结果进行转移的条件转移指令(检测zf、cf的值)和根据有符号数的比较结果进行转移的条件转移指令(检测sf、of、zf的值)
根据无符号数的比较结果进行转移的条件转移指令:
| 指令 | 含义 | 检测的相关标志位 |
|---|---|---|
| je | 等于则转移 | ZF=1 |
| jne | 不等于则转移 | ZF=0 |
| jb | 低于则转移 | CF=1 |
| jnb | 不低于则转移 | CF=0 |
| ja | 高于则转移 | CF=0且ZF=0 |
| jna | 不高于则转移 | CF=1或ZF=1 |
条件转移指令实质是根据所检测的相关标志位来进行条件判断是否发生转移的,与cmp指令结合使用时才会体现“等于则转移”等含义
编程
data段中的8个字节如下:
1 | data segment |
统计data段中数值为8的字节的个数,结果保存在ax中
1 | mov ax,data |
统计data段中数值大于8的字节个数,ax保存统计结果
1 | mov ax,data |
统计data段中数值小于8的字节的个数,ax保存统计结果
1 | mov ax,data |
DF标志和串传送指令
DF标志
标志寄存器第10位
方向标志位
作用:在串处理指令中,控制每次操作后SI、DI的增减
DF=0:每次操作后SI、DI递增
DF=1:每次操作后SI、DI递减
串传送指令
movsb
格式:movsb
功能:执行movsb指令相当于进行:
((es)*16+(di))=((ds)*16+(si))若
DF=0则:(si)=(si)+1,(di)=(di)+1若
DF=1则:(si)=(si)-1,(di)=(di)-1
将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器DF位的值,将si和di递增或递减
movsw
功能:将ds:si指向的内存单元中的字送入es:di中,然后根据标志寄存器DF位的值,将si和di递增2或递减2
一般来说,movsb和movsw都与rep配合使用,格式:rep movsb
rep movsb的功能:
1 | s: movsb |
rep的作用是:根据CX的值,重复执行后面的串传送指令。由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep movsb就可以循环实现(cx)个字符的传送
类似的,rep movsw的功能:
1 | s: movsw |
标志寄存器的DF位决定串传送指令执行后,si和di改变的方向,CPU提供相应的指令来对DF位进行设置
cld指令:将标志寄存器的DF位置0std指令:将标志寄存器的DF位置1
编程
将data段中的第一个字符串复制到其后面的空间中
1 | data segment |
使用串传送指令需提供的必要信息
传送的原始位置:
data:0传送的目的位置:
data:0010传送的长度:16
传送的方向:正向传送(向后),
DF=0(si和di递增)
1 | mov ax,data |
将F000H段最后16个字符用串传送指令复制到data段中
1 | data segment |
将ds:si指向F000H段的最后一个单元,将es:di指向data段中的最后一个单元,逆向传送16个字节
传送的起始位置:
F000:FFFF传送的目的位置:
data:000F传送的长度:16
传送的方向:逆向传送(向前),
DF=1(si和di递减)
1 | mov ax,0f000h |
pushf和popf
pushf功能是将标志寄存器的值压栈
popf功能是从栈中弹出数据,送入标志寄存器
为直接访问标志寄存器提供了一种方法
标志寄存器在Debug中的表示
在Debug中,标志寄存器是按照有意义的各个标志位单独表示的


| 标志位 | 值为1的标记 | 值为0的标记 |
|---|---|---|
| OF | OV | NV |
| SF | NG | PL |
| ZF | ZR | NZ |
| PF | PE | PO |
| CF | CY | NC |
| DF | DN | UP |