• 8086FLAG寄存器


             8086中的FLAG寄存器也就是状态标志位寄存器。它用来存储一些指令的计算结果,比如加法减法中的进位;为CPU运行某些命令提供根据,比如DF它决定是往前走指针还是向后走指针;总之状态寄存器存放的被称为程序状态字(PSW)。

             8086中的寄存器一共同拥有例如以下所看到的:

    1      ZF(0标志)

    指令的运行结果为0,就ZF=1,否则ZF为0。

    MOV AX,  1

    SUB  AX,   1;ZF = 1

    MOV AX,  2

    SUB AX,    1;ZF= 0

    2      PF(奇偶标志)

    结果中个1的个数为偶数则PF=1,否则PF = 0。

    MOV AL,  1

    ADD AL,   10;运行结果为:1011B。PF =0

    MOV AL,  1

    OR AL,      2;运行结果为:0011B,PF = 1

    3       SF(符号标志位)

             运行指令后。假设结果为负,则SF=1。否则SF=0

             SF是针对有符号数来讲的,它记录数据的正负,当我们把数据当做带符号的时候,只SF来推断结果的正负

    <1> 有无符号的区分

             汇编中的带符号数和无符号数:在汇编中事实上没有针对有无符号做出区分和标志,区不区分是人的主观看待的。比如:

    MOV AX 1000 0001B

    ADD AX,   1;

    当我们把运算当做无符号数来计算的时候,1000 0001B = 129,129 + 1 = 130;130的二进制表示1000 0010B。

    当我们把运算当做有符号数来计算的时候。1000 0001B = -127,-127 + 1 = -126.-126的补码是

    1000 0010B。

    可见无论怎么当做什么,最后的结构都表示都是一样的,仅仅只是是当做是无符号数的时候,你不必去把补码转换成原码,由于当做无符号数的时候,相当于给最高位前面加了1位。而且这位值是0;当做是符号位的时候,你自然要依据最后的补码再转换成原码了。

    <2>  溢出的问题

    关于符号位的计算,当我们计算加法的时候,最高位是符号位。问题是符号位參与运算没?

    答案是參与了。补码的的范围不包括符号位,可是补码相加后会产生进位,进位会与符号位參与运算,运算结果决定了终于的符号位。

    4      CF(进位标志)

    这个是针对无符号的运算的。表示加法的进位以及减法的借位。

    5      OF(溢出标志)

    这个标志是针对符号位的,当进行有符号的运算的时候。假设计算的范围超过了规定的范围。那么就会产生溢出。

    6       adc指令

    Adc指令是加法指令,它和add类似,仅仅只是是把进位值也相加了。

    利用adc指令能够非常方便的进行多进制数的叠加,仅仅须要開始的时候进位制设为0,然后就每次相加16位。就这样子非常easy。

    7       sbb指令

    带进位的减法。它的功能是:操作数1 – 操作数2 – 进位值(借位)

    8       CMP指令

    它运行的是:操作数1 – 操作数2;依据计算结果对寄存器进行设置,可是不保存结果。

    可是不能只sf的值去推断结果去推断比較结果的大小。

    由于sf是针对有符号的数字来说的,假设在进行计算的时候发生了溢出。就不能简简单单依据sf的值推断正负了,所以要依据溢出标志of和符号标志sf去综合推断。

    如: 34 –(-96) = 130,这时候of=1。sf=1。不能说明34< -96

    <1> sf = 1,of =0,说明A<B

    <2>sf = 1,of = 1,说明A>B

    <3>sf = 0,of = 0,说明A>B

    <4>sf = 0,of = 1,说明A<B

    9       依据比較结果的转移指令

    运行cmp指令后。会影响zf,pf,sf。cf。of,依据这些值的大小会有对应的跳转指令。

    Je,          zf =1,等于跳转

    Jne。        zf=0,不等于跳转

    Jb,          cf=1,低于跳转

    Jnb,        cf=0,不低于跳转

    Ja。          cf=0,且zf=0,高于则跳转

    Jna。        cf=1活zf=1,不高于则跳转

    10     DF(方向标志)

    它的值决定每次运行后si。di的值是递增还是递减

    有下面两个指令movsb,movsw。

    <1>movsb

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

    假设df =0,(si) = (si) + 1,(di) = (di) + 1

    假设df=1。(si) = (si) -1,(di) = (di) – 1

    <2>movsw

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

    假设df =0,(si) = (si) + 2,(di) = (di) + 2

    假设df=1。(si) = (si) -2,(di) = (di) – 2

    <3>rep

    这个表示反复的意思,有两种格式了

    Rep movsb。

    Rep movsw;

    分别相当于:

    S:movsb

    Loop S;

    S:movsw

    Loop S;

    <4>cld,std

    Cld,将标志位的df置0。std。将标志位的df置1.

    以下这个程序实现的是将ds中的字节的复制。

    MOV AX,DATA

    MOV DS,AX

    MOV SI,0

    MOV ES,AX

    MOV DI,16

    CLD

    REP MOVSB

    11     pushf和popf

    这个是将标志寄存器中的各位压栈和出栈

  • 相关阅读:
    【WPF on .NET Core 3.0】 Stylet演示项目
    【WPF on .NET Core 3.0】 Stylet演示项目
    [译]ABP v1.0终于发布了!
    Centos7 安装配置 Rabbitmq Cluster
    新系统添加sshkey/pexpect基本使用
    ansible Templates
    Jenkins Sonar
    Haproxy 安装及配置
    keepalived 安装及配置
    docker etcd
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5329559.html
Copyright © 2020-2023  润新知