CPU内部的寄存器中,有一种特殊的寄存器具有以下三种作用。
用来存储相关指令的某些执行结果
用来为CPU执行相关指令提供行为依据
用来控制CPU的相关工作方式
这种特殊的寄存器在8086CPU种,被称为标志寄存器(flag)。8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)。
8086CPU的flag寄存器的结构如下图。
flag的1、3、5、12、13、14、15位在8086CPU中没有使用,不具有任何含义。而0、2、4、6、7、8、9、10、11位都具有特殊含义。
一、ZF标志
flag的第6位是ZF,零标志位。它记录相关指令执行后,其结果是否为0。如果结果为0,那么ZF=1;如果结果不为0,那么ZF=0。
在8086CPU的指令集中,有的指令的执行是影响标志寄存器的,比如,add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算术运算);有的指令的执行对标志寄存器没有影响,比如:mov、push、pop等,它们大都是传送指令。在使用一条指令的时候,要注意这些指令的全部功能,其中包含执行结果对标志寄存器的哪些标志位造成影响。
二、PF标志
flag的第2位是PF,奇偶标志位。它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数。如果的个数为偶数,pf=1,如果为奇数,那么pf=0。
三、SF标志
flag的第7位是SF,符号标志位。它记录相关指令执行后,其结果是否为负。如果结果为负,sf=1;如果非负,sf=0.
SF标志,就是CPU对有符号运算结果的一种记录,它记录数据的正负。在我们将数据当作有符号数来运算的时候,可以通过它来得到结果的正负。如果我们将数据当作无符号来运算,SF的值则没有意义,虽然相关的指令影响了它的值。
四、CF标志
flag的第0位是CF,进位标志位。一般情况下,在进行无符号数运算的时候,记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。
五、OF标志
flag的第11位是OF,溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出。如果发生溢出,OF=1;如果没有,OF=0.
一定要注意CF和OF的区别:CF是对无符号运算有意义的标志位,而OF是对有符号运算有意义的标志位。
六、DF标志位和串传送指令
flag的第10位是DF,方向标志位。在串处理指令中,控制每次操作后si、di的增减。
df=0 每次操作后si、di递增
df=1 每次操作后si、di递减
下面有几个串传送指令
格式:movsb
功能:执行movsb指令相当于进行下面几步操作。
1) ((es)*16+(di)) = ((ds)*16+(si))
2) 如果df=0 则 (si)=(si)+1 (di)=(di)+1
如果df=1则: (si)=(si)-1 (di)=(di)-1
当然也可以传送一个字
格式:movsw
功能:将ds:si指向的内存单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2.
movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb和movsw都和rep配合使用,格式如下:
rep movsb
rep功能:根据cx的值,重复执行后面的串传送指令。由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep movsb就可以循环实现(cx)个字符的传送。
8086CPU提供下面两条指令对df位进行设置。
cld指令: 将标志寄存器的df位置0
std指令: 将标志寄存器的df位置1
1)编程,用串传送指令,将data段中的第一个字符串复制到它后面的空间中。
data segment
db'welcome to masm!'db16 dup (0)
data ends
code segmentmovax,datamovds,axmov si, 0
moves,axmov di,16
mov cx,16
cld
rep movsbcode ends
end
2)编程,用串传送指令,将F000段中的最后16个字符复制到data段中。
data segment
db16 dup (0)
data ends
code segmentmovax,0f000hmovds,axmovsi, 0ffffhmovax,datamoves,axmov di, 15
mov cx, 16
std
rep movsbcode ends
end