标志寄存器

CPU内部有一种特殊寄存器,用来存储相关指令的某些结果,用来为CPU执行相关指令提供行为依据,用来控制CPU的相关工作方式

这种寄存器在8086中称为标志寄存器,8086中的标志寄存器通常是16位,flag寄存器是每一位有每一位的意义和普通寄存器不同。

 

 

 

ZF标志

flag的第六位是ZF,zero flag,也就是0标志位,记录相关指令执行后,其结果是否为0,如果为0则zf=1,如果不为0,则zf=0.

;例
mov ax,2
sub ax,1
;执行结果后ax不为0则zf=0
mov ax,1
sub ax,1
;执行后结果为0,则zf=1

对于ZF寄存器,是在当结果为0的时候置为1,当结果为1的时候表示为0也很好理解,就是为0的时候zf就为真了

PF标志

flag的第二位是PF,奇偶标志位,记录执行相关指令后,的结果bit位中1的个数是否为偶数,如果1的个数为偶数,则pf=1,如果为奇数,pf=0

mov al,1
add al,10
;执行后结果为00001011B,有三个1,pf=0
mov al,1
or al,2
;执行后为00000011B,其中,有两个2,则pf=1

SF标志

符号表示位,执行相关指令后观察结果是否为负,如果结果为负,SF=1,如果非负sf=0

在计算机中通常用补码来表示有符号数,计算的数据可以看出无符号也可以看出有符号。

所以在CPU中的这个SF寄存器,默认用来考虑的是有符号数的操作,当你是想操作有符号数的时候这个SF标志寄存器才有用,否则并没有什么用

;比如
mov al,100000000b
add al,1
;这个时候sf肯定为1,关于为什么是负数,请查看补码的相关知识
指令zfpfsf
sub al,al 1 1 0
mov al,1 0 0 0
push ax 0 0 0
pop bx 0 0 0
add al,b1 0 1 1
add al,10      
mul al      

CF标志

flag寄存器的第0位是CF标志,仅为标志位,一般情况下只有在进行无符号数运算的时候,记录结果的最高有效位向更高位的进位制,或者从更高位的借位值

mov al,0xFFH
add al,0x1H
;这个时候al发生了进位CF=1

mov al,0x97H
sub al,0x98H
;执行后al=FFH,cf=1,记录了向更高位的借位值

OF标志

这里溢出只有在有符号数运算的时候才有囊括,其定义是:超过了机器所能表示的范围称为溢出

 

;例
mov al,98
add al,99
;这里的al应该来说是197D,但是因为al之恶能表示7位的有符号数的值,所以就是表达不了这个值,所以溢出了

需要注意的是CF和OF的区别,一个是针对无符号数,一个是有符号数

 

当面临无符号数的时候只需要看他的CF位就好,当面临有符号数的时候就需要看OF和SF位了

ADC指令(带进位加法)

adc是带进位加法指令,利用了CF位上记录的进位制

格式 adc 对象1,对象2

功能:对象1=对象1+对象2+CF

sbb指令(带进位减法)

格式:sbb 对象1,对象2

功能:对象1=对象1-对象2-CF

cmp指令

cmp是比较指令,相当于减法,但是不会保存结果,只是专门对表示寄存器有影响

格式:cmp 对象1,对象2

功能:计算操作对象1-操作对象2

但是不会保存任何结果,只是对标志寄存器有影响

 

;例
mov ax,8
mov bx,3
cmp ax,bx
;执行后ax和bx值不变
;zf=0,pf=1,sf=0,cf=0,of=0

也可以用对象1和对象2的大小来判断

利用cmp可以对有符号数和无符号数都可以比较

检测比较结果的条件转移指令

“转移”指的是能够修改IP,而“条件”指的是它可以根据某种条件,决定是否修改IP,通常会在cmp指令后有跳转转移指令

无符号数

检测zf和cf标志位的值

有符号数

检测sf、of和zf的值

比如,jcxz就是一个条件转移指令,可以检测cx中的数值,如果(cx)=0,就跳转ip,否则不变

常用的根据无符号数的比较结果进行转移的条件转移指令

 

 

记忆方法

e:表示equal

ne:表示not equal

b:表示below 小于

nb:表示not below 不小于

a:表示above 大于

na:表示not above 不大于

DF标志和串传送指令

flag的第10位是DF,方向标志位。在串处理指令中,控制每次操作后的si、di的递减

df=0 每次操作后si、di递减

df=1 每次操作后si、di递减

串传送指令

movsb

功能:(以字节为单位传送)

把ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器DF的值,将si和di递增或递减

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

如果:df=0

inc si

inc di

movsw

功能:以字为单位,别的不变,就是递增和递减变为增2减2

串传送

movsb和movsw都是和rep配合这使用才行

格式:rep movsb

相当于:

s:movsb

loop s

可见rep的作用是根据cx的值来重复执行穿传送指令,由于每次执行串传送指令si和di都会自己移动,所有可以循环实现(cx)个字符的传送

设置df位

在8086CPU中提供了两条指令来设置:

cld指令:将df设置为0

std指令:将df设置为1

pushf和popf

pushf的功能是将标志寄存器的值压栈,popf是将标志寄存器的值出栈