王爽《汇编语言》(第二版) 学习笔记 (第十一章 标志寄存器)

 

第十一章 标志寄存器
本章概述:
1.         CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理器,个数和结构都可能      不同)具有以下3种作用:
1)        用来存储相关指令的某些执行结果
2)        用来为CPU执行那个相关指令提供行为依据
3)        用来控制CPU的相关工作方式
2.         这种特殊的寄存器在8086CPU中,被称为标志寄存器。
3.         8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)。
4.         flag和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义。而flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。
一、             ZF 标志
1.         flag的第6位是ZF,零标志位。它记录相关指令执行后,其结果是否为0。如果结果为0,那么zf=1;如果结果不为0,那么zf=0;
2.         在计算机中1表示逻辑真,表示肯定,所以当结果为0的时候zf=1,表示“结果是0”。
3.         注意,在8086CPU的指令集中,有的指令的执行是影响标志寄存器的,比如:add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算术运算);有的指令的执行对标志寄存器没有影响,比如:mov、push、pop等,它们大都是传送指令。在使用一条指令的时候,要注意这条指令的全部功能,其中包括,执行结果对标志寄存器的哪些标志位造成影响。
二、             PF 标志
1.         flag的第2位是PF,奇偶标志位。它记录相关指令执行后,器结果的所有bit位中1的个数是否为偶数。如果1的个数为偶数,pf=1,如果为奇数,那么pf=0。
三、             SF 标志
1.         flag的第7位是SF,符号标志位。它记录相关指令执行后,其结果是否为负数。如果结果为负,sf=1;如果费负,sf=0。
2.         计算机中通常用补码来表示有符号数据。计算机中的一个数据可以看作是有符号数,也可以看成是无符号数。
3.         对于同一个二进制数据,计算机可以将它当做无符号数据来运算,也可以当做有符号数据来运算。
4.         SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负。在我们将数据当做有符号数来运算的时候,可以通过它来得知结果的正负。如果我们将数据当做无符号数来运算,SF的值则没有意义,虽然相关的指令影响了它的值。
5.         CPU在执行add等指令时,是必然要影响到SF标志位的值的。至于我们需不需要这种影响,那就看我们如何看待指令所进行的运算了。
6.         某些指令将影响标志寄存器中的多个标志位,这些被影响的标志位比较全面地记录了指令的执行结果,为相关的处理提供了所需的依据。比如指令sub al,al执行后,ZF、PF、SF等标志位都要受到影响,它们分别为:1、1、0。
四、             CF 标志
1.         flag的第0位是CF,进位标志位。一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。
2.         当2个数相加溢出时,CPU在运算的时候,并不丢失这个进位值,而是记录在一个特殊的寄存器的某一位上。8086CPU就用flag的CF位来记录这个进位值。
3.         当两个数据做减法的时候,有可能向更高位借位。
五、             OF 标志
1.         在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出。
2.         对于8位的有符号数据,机器所能表示的范围就是-128~127。同理,对于16位有符号数据,机器所能表示的范围是-32768~32767
3.         如果运算结果超过了机器所能表达的范围,将产生溢出。
4.         由于在进行有符号数运算时,可能发生溢出而造成结果的错误。则CPU需要对指令执行后是否产生溢出进行记录。
5.         flag的第11位是OF,溢出标志位。一般情况下,OF记录了有符号数运算的结果是否产生溢出进行记录。如果发生溢出,OF=1;如果没有,OF=0。
6.         要注意CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位。
7.         CF和OF所表示的进位和溢出,是分别对无符号数和有符号数运算而言的,它们之间没有任何关系。
六、             adc 指令
1.         adc是带进位加法指令,它利用了CF位上记录的进位值。
2.         指令格式:adc操作对象1,操作对象2
功能:操作对象1=操作对象1+操作对象2+CF
比如指令 adc ax,bx 实现的功能是:(ax)=(ax)+(bx)+CF
3.         在执行adc指令的时候加上的CF的值的含义,是由adc指令前面的指令决定的,也就是说,关键在于所加上的CF值是被什么指令设置的。显然,如果CF的值是被sub指令设置的,那么它的含义就是借位值;如果是被add指令设置的,那么它的含义就是进位值。
4.         CPU提供adc指令的目的,就是来进行加法的第二步运算的。adc指令和add指令相配合就可以对更大的数据进行加法运算。
5.         adc指令执行后,也可能产生进位值,所以也会对CF位进行设置。由于有这样的功能,我们就可以对任意大的数据进行加法运算。
6.         将CF设置为0:sub ax,ax
7.         inc和loop指令不影响CF位。
七、             sbb 指令
1.         sbb是带借位减法指令,它利用了CF位上记录的借位值。
指令格式:sbb 操作对象1,操作对象2
功能:操作对象1=操作对象1-操作对象2-CF
比如指令 sbb ax,bx 实现的功能是:(ax)=(ax)-(bx)-CF
sbb指令执行后,将对CF进行设置。利用sbb指令可以对任意大的数据进行减法运算。
2.         sbb和adc是基于同样的思想设计的两条指令,在应用思路上和adc类似。
八、             cmp 指令
1.         cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
2.         cmp指令格式:cmp 操作对象1,操作对象2
功能:计算操作对象1-操作对象2 但并不保存结果,仅仅根据计算结果对标志寄存器进行设置。
3.         通过cmp指令执行后,相关标志位的值就可以看出比较的结果。
cmp ax,bx
1)        如果(ax)=(bx),则(ax)-(bx)=0,所以:zf =1;
2)        如果(ax)!=(bx),则(ax)-(bx)!=0,所以:zf=0;
3)        如果(ax)<(bx),则(ax)-(bx)将产生借位,所以:cf=1;
4)        如果(ax)>=(bx),则(ax)-(bx)不必借位,所以:cf=0;
5)        如果(ax)>(bx),则(ax)-(bx)既不必借位,结果又不为0,所以:cf=0并且zf=0;
6)        如果(ax)<=(bx),则(ax)-(bx)既可能借位,结果可能不为0,所以:cf=1或zf=1。
4.         比较指令的设计思路:通过做减法运算,影响标志寄存器,标志寄存器的相关位记录了比较的结果。
5.         同add、sub指令一样,CPU在执行cmp指令的时候,也包含两种含义:进行无符号数运算和进行有符号数运算。所以利用cmp指令可以对无符号数进行比较,也可以对有符号数进行比较。用cmp进行无符号数比较时,相关标志位对比较结果的记录。
6.         由于cmp比较时可能会产生溢出,所以不能仅从sf的结果来判断大小,而不要结合of来判断大小:
1)        sf=1,of=0 A<B
2)        sf=1,of=1 A>B
3)        sf=0,of=1 A<B
4)        sf=0,of=0 A>=B
九、             检测比较结果的条件转移指令
1.         “转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件,决定是否修改IP。
2.         jcxz是一个条件转移指令,它可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做。所有条件转移指令的转移位移都是[-128,127]。
3.         除了jcxz之外,CPU还提供了其他条件转移指令,大多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP。它们检测的是被cmp指令影响的那些位,表示比较结果的标志位。这些条件转移指令通常都和cmp相配合使用,就好像call和ret指令通常相配合使用一样。
4.         因为cmp指令可以同时进行两种比较,无符号数比较和有符号数比较,所以根据cmp指令的比较结果进行转移的指令也分为两种,即根据无符号数的比较结果进行转移的条件转移指令(它们检测zf、cf的值)和根据有符号数的比较结果进行转移的条件转移指令(它们检测sf、of和zf的值)。
5.         下面是常用的根据无符号数的比较结果进行转移的条件转移指令:
1)        je             等于则转移            zf=1
2)        jne           不等于则转移        zf=0
3)        jb            低于则转移            cf=1
4)        jnb           不低于则转移        cf=0
5)        ja             高于则转移            cf=0且zf=0
6)        jna           不高于则转移        cf=1或zf=1
这些指令比较常用,它们都很好记忆,它们的第一个字母都是j,表示jump;后面的字母表示意义如下:
1)        e: 表示equal
2)        ne:表示not equal
3)        b: 表示below
4)        nb:表示not below
5)        a: 表示above
6)        na:        表示not  above
十、             DF 标志和串传送指令
1.         flag的第10位是DF,方向标志位。在串处理指令中,控制每次操作后si、di的递增。
1)        df=0,每次操作后si、di递增
2)        df=1,每次操作后si、di递减
2.         格式: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
3.         movsb的功能是将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增或递减。
4.         与movsb类似,movsw的功能是将ds:si指向的内存单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2。
5.         movsb和movsw进行的串传送操作中的一个步骤,一般来说,movsb和movsm都和rep配合使用,格式是:rep movsb。用汇编语法来描述rep movsb的功能就是:、
s:      movsb
       loop  s
6.         rep的作用是根据cx的值,重复执行后面的串传送指令。由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep    movsb就可以循环实现(cx)个字符的传送。rep movsw同理。
7.         由于flag的df位决定着串传送指令执行后,si和di改变的方向,所以CPU应该提供相应的指令来对df位进行设置,从而使程序员能够决定传送的方向。
8.         8086CPU提供下面两条指令对df位进行设置:
1)        cld指令:将标志寄存器的df位置为0
2)        std指令:将标志寄存器的df位置为1
十一、      pushf 和popf
1.         pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中。
2.         pushf和popf,为直接访问标志寄存器提供了一种方法。
十二、      标志寄存器在Debug 中的表示
在debug中,标志寄存器是按照有意义的各个标志位单独表示的。

实验11编写子程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值