首页 > 代码库 > 8086FLAG寄存器

8086FLAG寄存器

         8086中的FLAG寄存器也就是状态标志位寄存器,它用来存储一些指令的计算结果,例如加法减法中的进位;为CPU执行某些命令提供依据,例如DF它决定是往前走指针还是向后走指针;总之状态寄存器存放的被称为程序状态字(PSW)。

         8086中的寄存器一共有如下所示:

1      ZF(0标志)

指令的执行结果为0,就ZF=1,否则ZF为0。

MOV AX,  1

SUB  AX,   1;ZF = 1

MOV AX,  2

SUB AX,    1;ZF= 0

2      PF(奇偶标志)

结果中个1的个数为偶数则PF=1,否则PF = 0;

MOV AL,  1

ADD AL,   10;执行结果为:1011B,PF =0

MOV AL,  1

OR AL,      2;执行结果为:0011B,PF = 1

3       SF(符号标志位)

         执行指令后,如果结果为负,则SF=1,否则SF=0

         SF是针对有符号数来讲的,它记录数据的正负,当我们把数据当做带符号的时候,仅仅SF来判断结果的正负

<1> 有无符号的区分

         汇编中的带符号数和无符号数:在汇编中其实没有针对有无符号做出区分和标志,区不区分是人的主观看待的。例如:

MOV AX 1000 0001B

ADD AX,   1;

当我们把运算当做无符号数来计算的时候,1000 0001B = 129,129 + 1 = 130;130的二进制表示1000 0010B。

当我们把运算当做有符号数来计算的时候,1000 0001B = -127,-127 + 1 = -126.-126的补码是

1000 0010B。

可见不管怎么当做什么,最后的结构都表示都是一样的,只不过是当做是无符号数的时候,你不必去把补码转换成原码,因为当做无符号数的时候,相当于给最高位前面加了1位,并且这位值是0;当做是符号位的时候,你自然要根据最后的补码再转换成原码了。

<2>  溢出的问题

关于符号位的计算,当我们计算加法的时候,最高位是符号位,问题是符号位参与运算没?

答案是参与了。补码的的范围不包含符号位,但是补码相加后会产生进位,进位会与符号位参与运算,运算结果决定了最终的符号位。

 

4      CF(进位标志)

这个是针对无符号的运算的,表示加法的进位以及减法的借位。

5      OF(溢出标志)

这个标志是针对符号位的,当进行有符号的运算的时候,如果计算的范围超过了规定的范围,那么就会产生溢出。

6       adc指令

Adc指令是加法指令,它和add类似,只不过是把进位值也相加了。

利用adc指令可以很方便的进行多进制数的叠加,只需要开始的时候进位制设为0,然后就每次相加16位。就这样子很简单。

7       sbb指令

带进位的减法。它的功能是:操作数1 – 操作数2 – 进位值(借位)

 

8       CMP指令

它执行的是:操作数1 – 操作数2;根据计算结果对寄存器进行设置,但是不保存结果。

但是不能仅仅sf的值去判断结果去判断比较结果的大小。因为sf是针对有符号的数字来说的,如果在进行计算的时候发生了溢出,就不能简简单单根据sf的值判断正负了,所以要根据溢出标志of和符号标志sf去综合判断。

如: 34 –(-96) = 130,这时候of=1,sf=1,不能说明34< -96

<1> sf = 1,of =0,说明A<B

<2>sf = 1,of = 1,说明A>B

<3>sf = 0,of = 0,说明A>B

<4>sf = 0,of = 1,说明A<B

 

9       根据比较结果的转移指令

执行cmp指令后,会影响zf,pf,sf,cf,of,根据这些值的大小会有相应的跳转指令。

Je,          zf =1,等于跳转

Jne,        zf=0,不等于跳转

Jb,          cf=1,低于跳转

Jnb,        cf=0,不低于跳转

Ja,          cf=0,且zf=0,高于则跳转

Jna,        cf=1活zf=1,不高于则跳转

 

10     DF(方向标志)

它的值决定每次执行后si,di的值是递增还是递减

有以下两个指令movsb,movsw。

<1>movsb

( (es)*16 + (di) ) = ( (ds)*16 +(si) )

如果df =0,(si) = (si) + 1,(di) = (di) + 1

如果df=1,(si) = (si) -1,(di) = (di) – 1

<2>movsw

( (es)*16 + (di) ) = ( (ds)*16 +(si) )

如果df =0,(si) = (si) + 2,(di) = (di) + 2

如果df=1,(si) = (si) -2,(di) = (di) – 2

<3>rep

这个表示重复的意思,有两种格式了

Rep movsb;

Rep movsw;

分别相当于:

S:movsb

Loop S;

S:movsw

Loop S;

<4>cld,std

Cld,将标志位的df置0,std,将标志位的df置1.

下面这个程序实现的是将ds中的字节的复制。

MOV AX,DATA

MOV DS,AX

MOV SI,0

MOV ES,AX

MOV DI,16

CLD

REP MOVSB

 

11     pushf和popf

这个是将标志寄存器中的各位压栈和出栈