8086汇编-标志寄存器(11)
引言
1.8086CPU的标志寄存器有16位,其中存储信息通常被称为程序状态字(PSW)
2.我们已经使用过8086CPU的ax,bx,cx,dx,si,di,bp,sp,ip,cs,ss,ds,es等13个寄存器
3.本章中的标志寄存器【flag】是我们的最后一个寄存器
4.flag和其他寄存器不一样,其他寄存器是用存放数据的,都是整个寄存器具有一个含义
5.而flag寄存器是安位起作用,也就是说:它的每一位都有专门的含义,记录特定的信息
6.flag在8086CPU中,只有 0 2 4 6 7 8 9 10 11具有特殊的含义,其他位置都没有意义
1.ZF标志
1.flag的第6位是ZF,零标志位,它记录相关指令执行后
1 | 结果为0, ZF=1 |
2.比如
1 | mov ax,1 |
3.对于ZF的值,我们可以这样来看,ZF标志相关指令的计算结果是否为0,如果是0,则在ZF要记录下“是0”这样的肯定信息
1 | mov ax,1 |
4.我们使用一条指令的时候,要注意这条指令的全部功能,其中包括,执行结果对标志寄存器的哪些标志位造成影响
2.PF标志
1.PE,奇偶标志位。它记录指令执行后,结果的所有二进制位中的1的个数
1 | 为偶数,PE=1 |
2.比如
1 | mov al,1 |
3.SF
1.flag的第7位是SF,符号标志位,它记录指令执行后
1 | 结果为负SF = 1 |
有符号数和补码[课外知识,得学]
比如
1 | 00000001B,可以看作无符号1,或者有符号数+1 |
2.示例:
1 | mov al,10000001B |
我们可以将add指令的运算当作无符号数的运算,那么add指令相当于计算129+1,结果是130【10000010B】
也可以将add指令进行的运算当作有符号的运算,那么add指令相当于计算-127+1,结果为-126【10000010B】
不管我们如何看待,cpu在执行add等指令的时候,就已经包含了两种含义,也就得到用同一种信息来记录的2中结果
关键在于我们需要哪一种结果
3.SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负
4.CPU在执行add等指令的时候,必然要影响到SF标志位的值
5.至于需不需要,关键是看我们自己需不需要
某些指令将影响标志寄存器中的多个标志位,这些被影响的标志位比较全面的记录了指令执行结果,为相关的处理提供了所需的依据,至于需不需要这些结果全都看我们自己
4.CF标志
【相对于无符号数而言】
1.flag的第0位是CF,进位标志位
2.一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值
3.对于位数为N的无符号数来说,其对应的二进制信息的最高位,也就是第N-1位,的最高有限位,而假象存在的第N位,就是相对于最高有效位的更高位
我们知道,当2个数据相加的时候,可能产生从最高有效位向更高位的进位,这个更高位去哪里了呢?
比如
1 | mov al,98H |
在比如
两个8位的数据97H-98H,将产生借位,借位后,相当于是197H-98H,,而flag的cf位也可以用来记录这个借位值
5.OF标志
【对有符号数而言】
1.溢出
在进行有符号运算的时候,如结果超过了机器所能表示的范围称为溢出
2.什么是机器所能表示的范围?
add al,3 那么对于8位的有符号数据,机器所能表示的范围就是-128~127
3.如果我们使用add指令进行的是有符号数运算,则98+99=-59,这样的结果让人无法接受
造成这种情况的原因,就是实际结果是197,作为一个有符号数,在8位寄存器al中存放不下
由于在进行有符号数运算的时候,可能发生溢出而造成结果的错误。所以CPU需要对指令执行后是否参数溢出进行记录,从而有了OF
区别:CF和OF
1 | 1.CF是对无符号数运算有意义的标志位 |
无符号CF有符号PF+SF
6.adc指令
1.adc是带有进位加法指令,它利用了CF上记录的进位值
2.格式
1 | adc 操作对象1,操作对象2 |
3.功能:
1 | 操作对象1=操作对象1+操作对象2+CF |
4.在执行adc指令的时候加上的cf的值的含义,由adc指令前面的指令决定的,也就是说,关键在于所加上的cf的值是被什么指令设置的
1 | 显然,如果CF的值是被sub指令设置的,那么它的含义就是借位值;如果是被add指令设置的,那么就是进位值 |
5.我们来看一下两个数据:0198H和0183H如何相加
1 | 可以看出:分2步 |
6.和 add ax,bx有相同结果
1 | add al,bl |
可以看出adc指令的目的就是,进行加法的第二步运算
adc指令和add指令相配合可以对更大的数据进行运算
编程小任务
编程计算1EF000H+201000H,结果放在ax(高16位)和bx(低16位)
1 | mov ax,001EH |
adc指令执行后,也可能产生进位值,所以也会对CF位进行设置
7.sbb指令
1.sbb是带借位减法指令,它利用了CF位上记录的借位值
2.格式
1 | sbb操作对象1,操作对象2 |
3.功能
1 | 操作对象1=操作对象1-操作对象2-CF |
4..比如:sbb ax,bx
1 | (ax)=(ax)-(bx)-CF |
5.利用sbb指令,我们可以对任意大的数据进行剑法运算
比如:计算003E100OH-00202000H,结果放在ax 和 bx中
1 | mov bx,1000H |
8.cmp指令
1.cmp是比较指令,功能相当于减法指令,只是不保存结果
2.cmp指令执行后,将对标志寄存器产生影响
3.其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果
4.格式
1 | cmp 操作对象1 - 操作对象2 |
5.功能:计算操作对象1-操作对象2,但并不能保存结果,仅仅根据计算结果对标志寄存器进行设置
比如:cmp ax,ax
1 | ZF=1;PF=1;SF=0;CF=0;OF=0 |
6.在使用cmp指令的时候,也包含了2中含义
1 | 1.进行无符号运算 |
对于有符号数的操作,不能说SF=1则操作对象<操作对象2
1 | (ah)=22H,(bh)=0A0H |
当产生溢出的时候,就会影响半段
所以我们就需要一起考虑到溢出的情况,也就是 OF寄存器
1 | 1.SF=1,OF=0 |
9.检测比较结果的条件转移指令
1.被cmp指令影响的标志位,这些田间转移指令通常和cmp相配合使用
cmp指令的比较结果进行转移的指令分为2种
1 | 对于无符号数的检测 |
2.条件转移指令小结【对于无符号】
1 | je 等于则转移 ZF=1 |
编程训练
实现如果(ah)=(bh)则(ah)=(ah)+(ah)否则(ah)=(ah)+(bh)
1 | cmp ah,bh |
虽然je的含义是相等则转移,但是它进行的操作的是ZF=1则转移
je检测的是ZF位置,不管je前面是什么指令,只要CPU实现的时候je指令的时候,ZF=1那么就会发生转移
课堂练习
1 | 计算出data段种的8的个数 |
10.DF标志和串传送指令
1.flag的第10位是DF,方向标志位
2.在串 处理指令中,控制每次操作后si和di的增减
1 | DF=0 , 每次操作后 si di 递增 |
3.格式 movsb
1 | 功能(以字节位单位传送) |
4.格式 movsw
1 | 以字来传递 |
5.movsb和movsw进行的是串传送操作中第一个不走,一般来说,movsb和movsw都和rep配合使用,格式rep movsb
rep的作用是根据cx的值,重复执行后面串传送指令
由于没执行依次movsb si di都会变化,则rep movsb就可以循环实现(cx)个字符的传送
6.如何修改DF?
1 | cld 将DF设置成0 |
7.练习一手
1 | assume cs:code |
11.pushf 和 popf
1.pushf:将标志寄存器的值压入栈中
popf:从栈中弹出数据,送入标志寄存器中
2.pushf和popf,为直接访问标志寄存器提供了一种方法