• 8086标志寄存器


    CPU内部的寄存器中,有一种特殊的寄存器(对于不同的机器,个数和结构都有可能不同)具有以下三个功能:

    • 用来存储某些相关指令的执行结果
    • 用来为CPU执行相关的指令提供行为依据
    • 用来控制CPU的相关工作方式

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

    标志寄存器与其他寄存器不一样,其他寄存器是用来放数据的,都是整个寄存器具有一个含义,而标志寄存器是按位起作用的。

    8086中的标志寄存器的结构如下图所示:

    其中1、3、4、12、13、14、15位在8086中没有使用。另外对于有确切含义的每一位,我们称为标志位

    ZF标志

    标志寄存器的第六位是ZF,零标志位。他是记录相关指令执行后,其结果是否位零。如果为零,那么zf=1,如果不为零,那么zf=0

    比如指令:

    mov ax, 1
    sub ax, 1
    

    执行后,ax的结果为0,所以zf=1

    再比如:

    mov ax, 2
    sub ax, 1
    

    执行后,ax的结果不为0,所以zf=0

    在这里,有一点需要注意:在8086的指令集中,有的指令的执行是影响标志位的,比如add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算数运算);有的指令的执行对标志寄存器没有影响,比如mov、push、pop等,它们大都是传送指令。

    PF标志

    标志寄存器的第二位是PF,奇偶标志位。它记录相关指令执行后,其结果的所有bit位中1的个数是否位偶数。如果是偶数,pf=1,如果位奇数,pf=0

    比如指令:

    mov al, 1
    add al, 10
    

    执行后,al为00001011B,其中有3个1,所以pf=0

    再比如:

    mov al, 1
    or al, 2
    

    执行后结果为00000011B,其中有2个1,所以pf=1

    SF标志

    标志寄存器的第七位是SF,符号标志位。它记录相关指令执行后,其结果是否为负。如果为负,sf=1,如果非负,sf=0

    这里要明确一点,在计算机中,通常用补码来表示有符号的数据,计算机中的一个数据既可以看作有符号数,也可以看作无符号数。不管我们如何看待,当CPU在进行运算的时候,就已经包含了两种含义,也将的到同一种信息来记录的两种结果。关键在于我们的程序需要那一种。

    SF标志,是CPU对有符号数运算结果一种记录。如果我们将数据当作无符号数来运算,SF标志位则没有意义,虽然计算过程中影响了他的值。

    我个人在这里的更简单写的理解是计算后结果的最高位是否为1,为1,这sf=1,否则,sf=0

    比如指令:

    mov al, 100000001B
    add al, 1
    

    执行后结果为10000010B,sf=1,表示如果进行的是有符号运算的话,则结果为负

    再比如

    mov al, 10000001B
    add al, 01111111B
    

    执行后,结果为0,sf=0,表示,如果进行的是有符号运算,这结果为非负

    CF标志

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

    比如指令:

    mov al, 98H
    add al, al  ; 执行后(al)=30H, CF=1, 产生进位
    add al, al  ; 执行后(al)=60H, CF=0, 没有进位,或者说进位为0
    

    再比如:

    mov al, 97H
    sub al, 98H  ; 执行后(al)=FFH, CF=1, 产生借位
    sub al, al   ; 执行后(al)=0, CF=0, 借位为0
    

    OF标志

    标志寄存器的第11位是OF,溢出标志位。一般情况下,OF记录了 有符号数 的运算结果是否发生了溢出。如果发生了溢出,of=1,如果没有,of=0

    {% note success %} 这里一定要注意的是CF和OF的区别,CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位。 它们之间没有任何关系 {% endnote %}

    比如指令:

    mov al, 98
    add al, 99
    

    执行后,of=1,发生溢出,没有进位

    再比如:

    mov al, 0F0H
    add al, 78H
    

    执行后:of=0,没有溢出

    DF标志

    标志寄存器的第10位是DF,方向标志位。在串传送指令中,控制每次操作后si、di的增减。

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

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

    例如串传送指令movsb

    • 格式:movsb

    • 功能:执行下面几步操作:1、((es) x 16 + (di)) = ((ds) x 16 + (si)) 2、如果df=0,(si)=(si)+1, (di)=(di)+1。如果df=1,则(si)=(si)-1, (di)=(di)-1

    另外还有movsw,这时候就是一次传送一个字了,相应的si和di的+1-1也就变更成了+2-2

    一般,movsbmovsw一般配合指令rep指令使用,如rep movsb, 相当于

    s: movsb  ; 当然啦,在此之前要先设置cx寄存器
       loop s
    

    adc、sbb、cmp、pushf和popf指令

    再没有标志寄存器的时候,我们进行加减运算最多只能进行16位的加减运算,这在实际的应用中显然是不够的,那么有了标志寄存器,在结合adcsbb指令,我们就可以进行任意多位的数的加减法了

    adc指令

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

    • 指令格式:adc 操作对象1,操作对象2
    • 功能: 操作对象1 = 操作对象1 + 操作对象2 + CF

    比如:计算1EF000H + 201000H,结果放在ax(高16位)和bx(低16位)中:

    mov ax, 001EH
    mov bx, 0F000H
    add bx, 1000H
    adc ax, 0020H
    

    更多位数的数相加和以上同理

    sbb指令

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

    • 指令格式:sbb 操作对象1,操作对象2
    • 功能:操作对象1 = 操作对象1 - 操作对象2 - CF

    比如:计算003E1000H - 00202000H,结果保存在ax,bx中

    mov bx, 1000H
    mov ax, 003EH
    sub bx, 2000H
    sbb ax, 0020H
    

    cmp指令

    cmp是比较指令,功能相当于减法指令,只是不保存结果。执行后,对标志寄存器产生影响

    • cmp指令格式:cmp 操作对象1,操作对象2
    • 功能:计算操作对象1 - 操作对象2,但不保存结果

    经过cmp计算后,我们就可以用jejnejbjnbjajna指令进行跳转了。

    因为比较复杂,在这里就不具体说实现的细节了,具体在更。

    pushf和popf指令

    pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据送入标志寄存器

    这两个指令为直接访问寄存器提供了一种方法


    在这里,我们讨论了六种寄存器,另外还有IF,TF,和AF没有讨论,具体再更

  • 相关阅读:
    Neural Collaborative Filtering
    Attentional Factorization Machines: Learning the Weight of Feature Interactions via Attention Networks
    Statistical Comparisons of Classifiers over Multiple Data Sets
    Data Poisoning Attacks on FactorizationBased Collaborative Filtering
    Markov Chain
    Adversarial Personalized Ranking for Recommendation
    常见网络协议
    Python3 JWT的生成与验证
    Python3函数中如何理解递归
    Python3使用re模块解析正则表达式
  • 原文地址:https://www.cnblogs.com/tcctw/p/10662965.html
Copyright © 2020-2023  润新知