• 王爽《汇编语言》第三版 第十一章 标志寄存器


    引言

      8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)。

      我们己经使用过8086CPU的ax、bx、cx、dx、si、di、bp、sp、ip、cs、ss、ds、es等13个寄存器了。

      本章中的标志寄存器(以下简称为flag)是我们要学习的最后一个寄存器。

      flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。

      8086CPU的flag寄存器的结构:

      

      flag的1、3、5、12、13、14、15位在8086CPU中没有使用,不具有任何含义。而0、2、4、6、7、8、9、10、11位都具有特殊的含义。

     

    11.1 ZF标志

      flag的第6位是ZF,零标志位。它记录相关指令执行后,结果为0 ,ZF = 1;结果不为0,ZF = 0。

      在8086CPU的指令集中,有的指令的执行是影响标志寄存器的,比如:add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算术运算);

      有的指令的执行对标志寄存器没有影响,比如:mov、push、pop等,它们大都是传送指令。


    11.2 PF标志

      flag的第2位是PF,奇偶标志位。它记录指令执行后,结果的所有二进制位(最低有效字)中1的个数:为偶数,PF = 1;为奇数,PF = 0。


    11.3 SF标志

      flag的第7位是SF,符号标志位。它记录指令执行后,结果为负,SF = 1;结果为正,SF = 0。

      对于同一个二进制数据,计算机可以将它当作无符号数据来运算,也可以当作有符号数据来运算,实际上无关紧要,重要的是使用者如何看待。

      我们可以将add指令进行的运算当作无符号数的运算,那么add指令相当于计算129+1,结果为130(10000010B);

      也可以将add指令进行的运算当作有符号数的运算,那么add指令相当于计算-127+1,结果为-126(10000010B)。

      如果我们将数据当作无符号数来运算,SF的值则没有意义,虽然相关的指令影响了它的值。


    11.4 CF标志

      flag的第0位是CF,进位标志位。

      一种情况是两个数据做加法产生了最高位的进位,另外一种情况,当两个数据做减法的时候,有可能向更高位借位。


    11.5 OF标志

      在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出。

      CF是对无符号数运算有意义的标志位;而OF是对有符号数运算有意义的标志位。 


    11.6 adc指令

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

        格式:  adc 操作对象1,操作对象2

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

        比如:adc ax,bx 实现的功能是:(ax)=(ax)+(bx)+CF

      使用adc可以对任意大的数据进行加法运算。 


    11.7 sbb指令

      sbb是带错位减法指令,它利用了CF位上记录的借位值。

        格式:sbb 操作对象1,操作对象2

        功能:操作对象1=操作对象1–操作对象2–CF

        比如:sbb ax,bx实现功能: (ax) = (ax) – (bx) – CF

      使用sbb指令我们可以对任意大的数据进行减法运算。


    11.8 cmp指令

      cmp 是比较指令,功能相当于减法指令,只是不保存结果。

      cmp 指令执行后,将对标志寄存器产生影响。

        格式:cmp 操作对象1,操作对象2

        功能:计算操作对象1–操作对象2 但并不保存结果,仅仅根据计算结果对标志寄存器进行设置。


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

      

      e:表示equal;
      ne:表示not equal;
      b:表示below;
      nb:表示not below;
      a:表示above;
      na:表示not above。


    11.10 DF标志和串传送指令

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

        DF = 0:每次操作后si,di递增;
        DF = 1:每次操作后si,di递减。

      格式: movsb(w) 
      功能:(以字节为单位传送)
      1.((es)×16 + (di)) = ((ds) ×16 + (si))
      2.

        如果DF = 0则:

               (si) = (si) + 1
               (di) = (di) + 1
        如果DF = 1则:

               (si) = (si) - 1
               (di) = (di) - 1

      8086CPU提供下而两条指令对DF位进行设置:
        cld指令:将标志寄存器的DF位置0
        std指令:将标志寄存器的DF位置1

      movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb 和 movsw 都和rep配合使用,格式如下: rep movsb。

      rep的作用是根据cx的值,重复执行后面的串传送指令。

    11.11 pushf和popf

      pushf :将标志寄存器的值压栈;

      popf :从栈中弹出数据,送入标志寄存器中。


    11.12 标志寄存器在Debug中的表示

      在Debug中,我们可以看到类似下面的信息: 

      

      

    参考资料:《小甲鱼汇编零基础入门》

     

         《汇编语言》第三版

  • 相关阅读:
    easyui 如何为datagrid添加自定义列属性(如:width,align,editor)
    Oracle中如何修改已存在数据的列名的数据类型
    web 表单方式上传文件方法(不用flash插件)
    easyui datagrid怎么动态获取表头的列名及显示名称
    如何解决“HttpException (0x80004005): 超过了最大请求长度”问题
    oracle中“ORA-00060: 等待资源时检测到死锁” 或存储过程编译卡死 解决方法
    Chosen v1.8.7 动态添加下拉选项
    【转发】vue v-for循环的用法(索引,键值)
    Vue Select默认选择项设置方法
    Vue内部使用setInterval轮询数据,对象数据重新赋值后再次渲染数据
  • 原文地址:https://www.cnblogs.com/mubu/p/6379615.html
Copyright © 2020-2023  润新知