精华内容
下载资源
问答
  • 标志寄存器

    2021-01-01 23:00:16
    标志寄存器

    标志寄存器

    image-20210101225756662

    image-20210101225810140

    image-20210101225823814

    image-20210101225836167

    image-20210101225851796

    image-20210101225905912

    image-20210101225934115

    展开全文
  • 首先说一下标志寄存器的概念。在8086cpu中标志寄存器都是16位的,而其中存储的信息被称为程序状态字(一段包含系统状态的内存或者是硬件区域)。标志寄存器既然是寄存器,那么它也是用来存储信息的,只是它存储信息的...

    首先说一下标志寄存器的概念。在8086cpu中标志寄存器都是16位的,而其中存储的信息被称为程序状态字(一段包含系统状态的内存或者是硬件区域)。标志寄存器既然是寄存器,那么它也是用来存储信息的,只是它存储信息的方式与其他的寄存器不同而已。其他的寄存器是一个寄存器包含一个信息,而标志寄存器则可以包含多个信息。而标志寄存器之所以可以存储多个信息,是因为它的存储方式。在标志寄存器中,信息是被存储在位中的。标志寄存器中的每一个位都可以代表特定的信息。

    deeda8b634c4f1d158469af5de937acf.png

    这是我在网上找的一个标志寄存器的示意图。通过这张图片我们可以知道在标志寄存器中,哪些是用到的,哪些是没用到的。我就不在赘述了。接下来我们看一下这些位的具体含义。

    CF(carry flag):进位标志位。这个位是在进行无符号数运算的时候用到的。一般情况下,这个位记录了进行无符号运算的时候,运算结果的最高有效位向更高位的进位值,或从更高位的借位值。注意的是,这里的进位与借位,都是相对于二进制而言的。下面我们再找一张图来加深下理解。

    4fb13c05bc999ed3581f7e9924eff23d.png

    PF(parity flag):奇偶标志位。这个位的判断需要我们将结果转为二进制来看,如果结果的低8位中有偶数个1,就将PF的值置1;如果是奇数个1,就置0。要注意的是一定是结果的低8位。

    PF,奇偶标志位,flag的第2位记录相关指令执行后,其结果所有bit位中1的个数是否为偶数,若为偶数,则PF=1;若为奇数,PF=0.

    执行

    mov al,00000000b

    add al,00000111b

    mov al,00000000b

    add al,00000011b

    验证:

    46eb4f8b12945fcec1a2339d5c87fb1c.png

    AF(auxiliary flag):辅助进位标志位。这个位用的不多,所以书上也没有讲,我就简单的查了一下资料。这个位表示加减法做到一半时有没有形成进位/借位,如果有则AF=1。这么说谁都听不懂,所以我们举个例子来说下。例如 MOV AL,00001110 MOV BL,00001000 ADD AL,BL 最后结果为AL=00010110这就是低四位向高四位进位。反之在减法中第三位不够减向第四位借位(注意数位是从第0位开始数的)叫低四位向高四位借位!像前面的AL中前四位为高四位,后四位为低四位。例如,当两个字节相加时,如果从低4位向高4位有进位时,则AF=1。

    ZF(zero flag):零标志位。这个位就很简单了,判断结果是不是0。如果结果为0,就置1;不为0,就置0。

    执行

    mov ax,1

    sub ax,1

    mov ax,2

    sub ax,1

    6fbd092263109c721883c262cf4a21cc.png

    可以看到 当计算ax结果为0时,ZF是ZR=1;结果为1(不为0)时,ZF是NZ=0.

    SF(sign flag):符号标志位。既然是符号标志位,就是对有符号数据来说的。如果结果为负,就置1;结果为正,就置0。

    SF,符号标志位,flag的第7位,记录相关指令执行后,其结果是否为负,若为负,则SF=1;若为非负,SF=0.

    执行:

    mov al,10000001b

    add al,1

    mov al,10000000b

    add al,01111111b

    验证:

    bcc05f371825a335c9ea62469281e964.png

    当SF=1即为NG,表示:若指令进行有符号数运算,则结果为负

    当SF=0即为PL,表示: 若指令进行有符号数运算,则结果为非负

    TF(timer overblow flag):定时器溢出标志。这个位主要是用来在debug中进行-t指令时使用的。当cpu在执行完一条指令后,如果检测到TF位的值为1,则产生单步中断,引发中断过程。通过这个位,我们就可以在debug中对程序进行单步跟踪。

    IF(interrupt flag):中断允许标志位。当IF=1时,cpu在执行完当前指令后响应中断,引发中断过程;当IF=0时,则不响应可屏蔽中断。

    DF(direction flag):方向标志位。在串处理指令中,控制每次操作后,si(指向原始偏移地址)、di(指向目标偏移地址)的增减。当DF=0时,每次操作后,si、di递增;DF=1时,每次操作后,si、di递减。我们可以使用cld指令将DF的值置为0,使用std指令将DF的值置为1。DF需要与rep、movsb等指令配合使用。

    OF(overflow flag):溢出标志位。这个位是用来判断有没有溢出的。注意溢出这个概念只对于有符号数据而言,就如同进位只对于无符号数据而言。当OF=0时,说明没有溢出;当OF=1时,说明溢出了。

    OF,溢出标志位,flag的第11位,超出机器所能表示的范围称为溢出若发生了溢出OF=1,若没有则OF=0

    比如对于8位有符号数据,机器能表示范围是 -128~127;对于16位有符号数据,范围是 -32768~32767

    执行:

    mov al,64

    add al,64

    mov al,63

    add al,64

    验证:

    62195edf8515f46bd1a29798c8658208.png

    下面有几个串传送指令

    格式: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

    当然也可以传送一个字

    格式:movsw

    功能:将ds:si指向的内存单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2.

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

    rep movsb

    rep功能:根据cx的值,重复执行后面的串传送指令。由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep movsb就可以循环实现(cx)个字符的传送。

    8086CPU提供下面两条指令对df位进行设置。

    cld指令: 将标志寄存器的df位置0

    std指令: 将标志寄存器的df位置1

    1)编程,用串传送指令,将data段中的第一个字符串复制到它后面的空间中。

    data segment

    db ‘welcome to masm!’

    db 16 dup (0)

    data ends

    code segment

    mov ax,data

    mov ds,ax

    mov si, 0

    mov es,ax

    mov di,16

    mov cx,16

    cld

    rep movsb

    code ends

    end

    2)编程,用串传送指令,将F000段中的最后16个字符复制到data段中。

    data segment

    db 16 dup (0)

    data ends

    code segment

    mov ax,0f000h

    mov ds,ax

    mov si, 0ffffh

    mov ax,data

    mov es,ax

    mov di, 15

    mov cx, 16

    std

    rep movsb

    code ends

    end

    打开APP阅读更多精彩内容

    点击阅读全文

    展开全文
  • 标志寄存器(8086CPU)作用用来存储相关指令的某些执行结果用来为CPU执行相关指令提供行为依据用来控制CPU的相关工作方式大小标志寄存器有16位使用方式标志寄存器是按位起作用,也就是说每一个位都有专门的含义,记录...

    标志寄存器(8086CPU)

    作用

    用来存储相关指令的某些执行结果

    用来为CPU执行相关指令提供行为依据

    用来控制CPU的相关工作方式

    大小

    标志寄存器有16位

    使用方式

    标志寄存器是按位起作用,也就是说每一个位都有专门的含义,记录特定的i西南西

    9c72af03f3dc377c43cc80df94b7666c.png

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

    ZF标志,在第6位,结果为0则为1,否则为0

    zf (Zero Flag) 是零标志位,在第6位;它记录相关指令执行后,其结果是否为0,如果为0,那么zf = 1;否则zf = 0

    例如

    mov ax, 1

    sum ax, 1

    执行后, 结果为0,则zf = 1

    mov ax, 2

    sum ax, 1

    执行后,结果不为0,则zf = 0

    注意

    在指令执行的过程中,有些指令对标志寄存器有影响,比如:add、sum、mul、div、inc、or、and等,他们大都是运算指令;而有些指令对标志寄存器没有影响,比如:mov、push、pop等,他们大都是传送指令。在使用一条指令的时候,要注意这条指令的全部功能,其中包括,执行结果对标志寄存器的哪些标志位产生了影响。

    PF标志,在第2位,结果中1的个数为偶数则为1,否则为0

    pf( Parity Flag)表示奇偶标志位,在第2位;他记录的是相关指令执行后,如果所有的bit位中1的个数是否为偶数。如果1的个数位偶数,pf = 1,如果为奇数,那么pf = 0

    例如:

    mov al, 1

    add al, 10

    执行后结果为1011B,其中有3(奇数)个1,则pf = 0

    mov al, 1

    or al, 2

    执行后,结果为:11B,其中有2(偶数)个1,则pf = 1

    SF 标志,在第7位,结果为负则为1,否则为0;有符号运算有效

    sf(Symbol Flag)表示符号标志位,在第7位;它记录相关指令执行后,其结果是否为负。如果为负,则sf = 1;如果非负,sf = 0

    通常CPU计算的时候有两种方式,一种是有符号的计算,一种是无符号的计算。

    SF标志,就是CPU对有符号数运算结果的一种记录,他记录数据的正负。

    如果我们将数据进行无符号运算,SF的值则没有意义,虽然相关指令影响了他的值

    例子:

    mov al, 10000001B

    add al, 1

    执行后,结果为10000010B,sf = 1,表示:如果指令进行是有符号运算,那么结果为负

    mov al, 10000001B

    add al, 01111111B

    执行后,结果为0,sf = 0;表示:如果指令记性的是有符号数运算,那么结果为0

    CF标志,在第0位,存储进位或借位的值

    cf(Carry Flag)表示进位标志位,在第0位。在进行无符号运算的时候,他记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值

    对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N-1为,就是他的最高位,而假想存在的第N位,就是相对于最高有效位的更高位

    63b2a239c8ea0814d95bf369d6d99d48.png

    ​我们都知道,在两个数相加的时候,会往更高的位进位;比如98H + 98H,将产生进位。由于这个进位值在8位数中无法进行报错。我之前认为这个数就丢失了。其实CPU在运算的时候,并不丢弃这个值,而是记录在CF标志位上面。

    例如

    mov al, 98H

    add al, al

    执行后:(al) = 30H, CF = 1,CF 记录了从最高有效位向更高位的进位值

    再次执行add al, al

    执行后:(al) = 60H, CF = 0, CF记录了从最高有效位向更高位的进位值

    而在做减法的时候,有可能向更高位借位;比如,两个8位数据97H - 98H,将产生借位。借位后相当于计算197H-98H;CF来记录这个借位值,例如下面的指令

    mov al, 97H

    sub al, 98H ; 执行后:(al) = FFH, CF=1, CF记录了向更高位的借位值

    sum al, al ; 执行后:(al) = 0, CF = 0, CF 记录了向更高位的借位值

    OF标志,在第11位,结果溢出则为1,否则为0;没理解透彻

    of( Overflow Flag)表示溢出标志位,在第11位。它记录了有符号数运算的结果是否产生了溢出,如果产生了溢出,of = 1;如果没有,OF = 0

    CPU在执行add等指令的时候,就包含了两种含义:

    无符号数运算

    有符号数运算

    对于无符号数运算,CPU用CF来记录是否产生了进位;对于有符号数运算,CPU用OF来记录是否产生了溢出。当然还要用SF来记录结果的符号。对于无符号数运算98+99没有进位,CF = 0;对于有符号数运算,98 + 99发生溢出,OF= 1

    mov al, 0F0H

    add al, 88H

    add指令执行后:CF = 1, OF= 1。对于无符号数运算,0F0 + 88H有进位CF= 1, 对于有符号运算,0F0H + 88H发生溢出,OF = 1

    mov al, 0F0H

    add al, 78H

    add指令执行后:CF = 1, OF = 0。对于无符号运算,0F0 + 78H有进位,CF = 1;对于有符号运算,0F0 + 78H不会发生溢出, OF = 0

    每一个有符号数,似乎都对应着一个无符号数,我们如何知道CPU在执行运算指令的时候,进行的是有符号运算还是无符号运算呢??????????????

    DF标志

    df( Direction Flag), 第10位。在串处理指令中, 控制每次操作后si、di的递减

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

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

    通过cld和std指令来进行设置DF的标志

    然后用req movsb/movsw进行复制数据

    串传送指令movsb

    将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增或递减

    格式:movsb

    功能:执行movsb指令相当于执行下面几步操作

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

    如果df = 0则:(si) = (si) + 1, (di) = (di) + 1

    如果df = 1则:(si) = (si) - 1,(di) = (di) - 1

    movsb的功能可以这样描述mov es:[di], byte ptr ds:[si],但是8086CPU没有这样的指令。

    如果df = 0

    inc si

    inc di

    如果df = 1

    dec si

    dec di

    串传送指令movsw

    movsw功能是将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2

    movsw的功能可以这样描述mov es:[di]. word ptr es:[si] 8086不支持这样的指令,这里只是描述

    如果df = 0

    add si, 2

    add di, 2

    如果df = 1

    sub si, 2

    sub di, 2

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

    reg movsb

    用汇编语法来描述req movsb的功能是:

    s:

    movsb

    loop s

    cld和std设置DF标志位

    cld 指令:将标志寄存器df位,置0

    std 指令:将标志寄存器的df位,置1

    adc 指令,带位加法指令,用于计算特别大的数据

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

    指令格式:abc 操作对象1, 操作对象了

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

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

    例:

    mov ax, 2

    mov bx, 1

    sub bx, ax

    adc ax, 1

    执行后,(ax) = 4。adc执行时,相当于计算:(ax) + 1 + CF = 2 + 1 + 1 = 4

    mov ax, 1

    add ax, ax

    adc ax, 3

    执行后,(ax = 5). adc执行时,相当于计算: (ax) + 3 + CF = 2 + 3 + 0 = 5

    mov al, 98H

    add al, al

    adc al, 3

    执行后,(al) = 34H。adc执行时,相当于计算:(al) + 3 + CF = 30H + 3 + 1 = 34H

    可以看出,adc指令比add指令多加了一个CF位的值。

    为啥要加呢?为啥要有这样一条指令呢? 看一下两个数据0198H和0183H

    adc.png

    可以看出加法是分两步进行的

    低位相加

    高位相加再加上低位相加产生的进位值

    下面的指令和add ax, bx具有相同的值

    add al, bl

    adc ah, bh

    CPU提供adc指令的目的,就是来进行加法的第二步运算的,比如我们需要计算特别大的数据的时候可以采用这种方式

    sbb 指令, 带借位减法指令,用于运算特别大的数据

    带位减法指令,利用CF位上记录的借位值

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

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

    比如指令sbb ax, bx 实现的功能是:(ax) = (ax) - (bx) - CF

    cmp指令,这个玩意有点复杂(P234, 11.8)

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

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

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

    比如,指令cmp ax, ax做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅仅影响flag的想改给为。指令执行后:zf = 1, pf = 1, sf = 0, cf = 0, of = 0

    下面的指令:

    mov ax, 8

    mov bx, 3

    cmp ax, bx

    执行后:(ax) = 8, zf = 0, pf = 1, sf = 0, cf = 0, of = 0

    其实我们通过cmp指令执行后,相关标志位的值就可以看出比较的结果

    cmp ax, bx

    如果(ax) = (bx) 则(ax) - (bx) = 0, 所以zf = 1;

    如果(ax) != (bx) 则(ax) - (bx) != 0, 所以zf = 0;

    如果(ax) < (bx) 则(ax) - (bx) 将产生借位, 所以cf = 1;

    如果(ax) >= (bx) 则(ax) - (bx) 不必借位, 所以cf = 0;

    如果(ax) > (bx) 则(ax) - (bx)既不借位,结果又不为0, 所以cf = 1并且zf = 0;

    如果(ax) <= (bx) 则(ax) - (bx) 既可能借位,结果可能为0, 所以cf = 1或zf = 1;

    指令cmp ax, bx的逻辑含义是比较ax和bx中的值,如果执行后

    zf = 1,说明(ax)=(bx)

    zf = 0,说明(ax)!=(bx)

    cf = 1,说明(ax)

    cf = 0,说明(ax)>=(bx)

    cf = 0并且zf = 0,说明(ax)>(bx)

    cf = 1或zf = 1,说明(ax)<=(bx)

    以上是无符号的比较逻辑

    cmp既可以对无符号进行比较,也可以对有符号进行比较,上面所说的是对无符号数进行比较时,相关标志位对比结果的记录

    有符号的比较结果

    如果因为溢出导致实际结果为负,那么逻辑上真正的结果必然为正。

    如果因为溢出导致实际结果为正,那么逻辑上真正的结果必然为负

    pushf和popf

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

    pushf和popf,为直接访问标志寄存器提供了一种方法

    标志寄存器在debug中的表示

    54f2b8f7a057e146a51edcdda330fff5.png

    4d1ed445e3a3b11bb62b5461beab343a.png

    展开全文
  • 转载自:http://www.cnblogs.com/dennisOne/archive/2012/10/23/2736238.html☞标志寄存器综述8086CPU的标志寄存器(flagsRegister, FR)有16位,其中存储的信息通常被称为程序状态字(PSW),flag寄存器与其他寄存器不同...

    转载自: http://www.cnblogs.com/dennisOne/archive/2012/10/23/2736238.html

    ☞标志寄存器综述

    8086CPU的标志寄存器(flags Register, FR)有16位,其中存储的信息通常被称为程序状态字(PSW),flag寄存器与其他寄存器不同,flag寄存器是按位起作用的。8086的flag寄存器中有CF、PF、ZF、SF、OF、DF标志位。

    3b468b5a8cd7d60dc990f0520d9a5207.png

    8086的FR的9个标志位

    标志位

    名称

    功能

    ZF

    零标志位(Zero Flag)

    判断结果是否为0。运算结果0,ZF置1,否则置0。

    PF

    奇偶标志位(Parity Flag)

    反映运算结果低8位中'1'的个数。'1'的个数为偶数,PF置1,否则置0。

    SF

    符号标志位(Sign Flag)

    反映运算结果的符号。运算结果为负,SF置1,否则置0。

    CF

    进位标志位(Carry Flag)

    反映无符号运算是否产生进位或借位。运算结果的最高有效位向更高位进位或者借位,CF置1,否则置0。

    OF

    溢出标志位(Overflow Flag)

    反映有符号运算是否溢出。运算结果超过了8位或者16位有符号数的表示范围,OF置1,否则置0。

    AF

    辅助进位标志位(Auxiliary Flag)

    在字节操作时低半字节向高半字节进位或借位。字操作时低字节向高字节进位或借位,AF置1,否则置0。

    DF

    方向标志位(Direction Flag)

    决定串处理指令控制每次操作后si、di的增减。df=0,则每次操作后si、di递增,否则递减。

    IF

    中断标志位(Interrupt Flag)

    决定CPU是否响应外部可屏蔽中断请求。IF为1时,CPU允许响应外部的可屏蔽中断请求。

    TF

    陷阱标志位(Trap Flag)

    TF被设置位1时,CPU进入单步模式,所谓单步模式就是CPU在每执行一步指令后都产生一个单步中断。主要用于程序的调试。8086/8088中没有专门用来置位和清零TF的命令。

    影响标志位的指令

    在8086CPU的指令集中,诸如add/sub/mul/div/inc/or/and这些逻辑或者算术运算影响FR;而诸如mov/push/pop等传送指令的执行不影响FR。

    执行一条指令,要注意这条指令的全部功能(特别是cmp),执行结果对FR的那些标志位造成影响。

    某些指令将影响FR中的多个标志位。

    修改标志位的常用方法

    pushf和popf提供了直接访问标志寄存器的一种方法。

    pushf的功能是将标志寄存器的值压栈;而popf是从栈中弹出数据。比如:

    pushf ; 将FR的值压栈

    pop ax ; (ax)=(FR)

    ; 处理ax

    push ax ; 将修改后的(ax)压栈

    popf ; (FR)=(ax)

    sub ax, ax 可以将CF设置为0,ZF设置为0。

    修改DF

    cld ; 将DF置为0

    std ; 将DF置为1

    FR在debug中的表示

    dd41bf0f3e6437f6bccf7f36c7a38bee.png

    标志位

    =1

    =0

    ZF

    ZR[Zero]

    NZ[Not Zero]

    PF

    PE[Parity Even]

    PO[Parity Odd]

    SF

    NG[Negative]

    PL[Plus]

    CF

    CY[Carry]

    NC[No Carry]

    OF

    OV[Overflow]

    NV[Not Overflow]

    AF

    AC[Auxiliary Carry]

    NA[No Auxiliary Carry]

    DF

    DN[Down]

    UP[UP]

    IF

    EI[Enable Interrupt]

    DI[Disable Interrupt]

    TF

    ------------------------------

    --------------------------------

    ☞从CPU的角度看待指令

    以下列指令进行讲解:

    mov al, 10000001B

    add al, 1

    CPU在执行add等指令的时候,就已经包含了两种含义(有符号和无符号运算),也将得到同一种信息来记录的两种结果。关键在于我们的程序需要哪一种结果。

    通过FR的PSW,我们可以根据需要来看待指令进行的运算。

    可以讲add指令进行的运算当做无符号数的运算,那么add指令相当于计算129+1,结果是130(10000010B);也可以将add指令进行的运算当做有符号的运算,那么add指令相当于-127+1,结果也就是-126(10000010B)。

    ☞adb指令和sbb指令

    指令

    指令格式

    功能

    示例

    带进位加法指令adc

    adc op1, op2

    op1=op1+op2+CF

    adc ax,bx

    带借位减法指令sbb

    sbb op1, op2

    op1=op1-op2-CF

    sbb ax,bx

    Q: 编写一个程序,对两个128位数据进行相加。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    1 assume cs:code, ds:code

    2

    3 data segment

    4 db 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h

    5 db 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h

    6 data ends

    7

    8 code segment

    9 start: mov ax, data

    10 mov ds, ax

    11 mov si, 0

    12 mov di, 8

    13

    14 mov cx, 8

    15

    16 call add128

    17

    18 mov ax, 4c00h

    19 int 21h

    20

    21 add128: ; 子程序开始

    22 push ax

    23 push cx

    24 push si

    25 push di

    26

    27 sub ax, ax ; 将CF置0

    28

    29 mov cx, 8

    30 s: mov ax, [si]

    31 adc ax, [di]

    32 mov [si], ax

    33 inc si ; inc不会影响CF的值;但是add si,2会影响CF的值

    34 inc si

    35 inc di

    36 inc di

    37 loop s

    38

    39 pop di

    40 pop si

    41 pop cx

    42 pop ax

    43

    44 ret

    45 code ends

    46 end start

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    ☞DF标志和串传递指令

    指令

    功能

    解释

    movsb

    传送字节单元

    mov es:[di], byte ptr ds:[si] ;8086不支持这样的指令,这里示意

    如果df=0

    inc si

    inc di

    如果df=1

    dec si

    dec di

    movsw

    传送字单元

    mov es:[di], word ptr ds:[si] ;8086不支持这样的指令,这里示意

    如果df=0

    add si, 2

    add di, 2

    如果df=1

    sub si, 2

    sub di, 2

    rep movsb

    串传送

    s: movsb

    loop s

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

    rep movsw

    串传送

    s: movsw

    loop s

    ☞cmp指令

    cmp指令概述

    cmp是比较指令,cmp的功能相当于减法指令,但是不保存结果[猜测:CPU可能使用不能被外界使用的某个寄存器进行暂存?]。cmp指令执行后,将对标志寄存器产生影响。

    指令格式

    功能

    示例

    cmp op1, op2

    计算op1-op2,但不保存结果,仅仅根据结果对标志寄存器产生影响。

    cmp ax, ax

    执行指令后:zf=0,pf=1,sf=0,cf=0,of=0

    和sub指令一样,CPU在执行cmp指令时,也包含两种含义:进行无符号数和有符号数运算。

    cmp ax, bx当做"无符号数运算"的含义[根据zf和cf进行解释]

    41675955848e141817799859bd42de88.png

    反过来:

    48bf5df16ceebbf1ab5683cf74cfa150.png

    根据无符号数的比较结果进行转移的条件转移指令(短转移)的原理就是基于上表。

    d6ddbcb43a7e3d568f27e26e399ce973.png

    cmp ax, bx当做"有符号数运算"的含义[根据zf/sf/of进行解释]

    【公理】:进行有符号数运算时,如果发生溢出(of=1),说明实际运算结果与逻辑运算结果不等;如果没有溢出(of=0),说明实际运算结果与逻辑运算结果一致。

    bfc44fefd1570054719b0d7968aa350b.png

    ☞cmp指令和条件转移指令的联合使用

    49e83c5082c3a790e7e52ea88e561dfb.png

    e6162e91601a3ebb095dcd2491fbc909.png

    总结:题(1)中"等于"和题目(2)中"大于"需要进行特别处理,所以应该讲"不等于"和"不大于"的直接跳出,这样可以使得程序更加简洁。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,790
精华内容 1,516
关键字:

标志寄存器