汇编语言——第11章 标志寄存器

这篇具有很好参考价值的文章主要介绍了汇编语言——第11章 标志寄存器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录​​​​​​​

引言

11.1 ZF标志

11.2 PF标志

11.3 SF标志

检测点11.1

11.4 CF标志

11.5 OF标志

检测点11.2

11.6 abc指令

11.7 sbb指令

11.8 cmp指令

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

检测点11.3

11.10 DF标志和串传送指令

1、DF标志

2、串传送指令

11.11 pushf和popf

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


引言

CPU内部的寄存器中有一种特殊的寄存器,被称为标志寄存器,具有以下三种作用,:

(1)用来存储相关指令的某些执行结果;

(2)用来为CPU执行相关指令提供行为依据;

(3)用来控制CPU的相关工作方式。

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

标志寄存器(简称为flag)。flag寄存器是按位起作用的,每一位都有专门的含义,记录特定的信息,与其他寄存器不一样。

8086 CPUflag寄存器的结构:

标志寄存器,汇编语言学习笔记,web安全,网络安全

flag13512131415位在8086 CPU中没有使用,不具有任何含义;而02467891011位都具有特殊的含义。

11.1 ZF标志

flag的第6位是ZF,零标志位,它记录相关指令执行后,结果为0ZF=1(记录下是0这样的肯定信息),结果不为0ZF=0(表示结果非0)

mov ax,1

sub ax,1

mov ax,1

and ax,0

指令执行后,结果为0,则ZF=1

mov ax,2

sub ax,1

mov ax,1

or ax,0

指令执行后,结果为1,则ZF=0

8086CPU,addsubmuldivincorand等它们大多都是运算(逻辑运算或是算术运算)指令,是影响标志寄存器的,而movpushpop等传送指令对标志寄存器一般没有影响,因为不会产生结果。

11.2 PF标志

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

mov al,1

add al,10

执行结果为00001011B,有31,则PF=0

mov al,1

or al,10

执行后结果为00000011B,有21,则PF=1

11.3 SF标志

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

计算机中通常用补码来表示有符号数据。计算机中的一个数据可以看作是有符号数,也可以看作是无符号数。也就是说,对于同一个二进制数据,计算机可以把它当作无符号数据来运算,也可以当作有符号数据来运算。CPU在执行add等指令的时候,就已经包含了两种含义,也将得到用同一种信息来记录的两种结果。

在我们将数据当作有符号数来运算的时候,可以通过它来得知结果的正负。如果我们将数据当作无符号数来运算,SF的值则没有意义,虽然相关的指令影响了它的值。

检测点11.1

标志寄存器,汇编语言学习笔记,web安全,网络安全

11.4 CF标志

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

对于位数为N的无符号数,其对应的二进制信息的最高位,即第N-1位,就是它的最高有效位,假想存在第N位是相对于最高有效位的更高位。标志寄存器,汇编语言学习笔记,web安全,网络安全

两个8位的数据运算可能产生进位或者借位,由于这个进位值在8位数中无法保存,8086CPU就用flagCF位来记录这个进位值。

mov al.98h

add al,al      ;执行后(al)=30Hcf=1cf记录了从最高有效位向更高位的进位值

add al,al      ;执行后(al)=60Hcf=0cf记录了从最高有效位向更高位的进位值

mov al,97h

sub al,98h   ;执行后(al)=ffhcf=1cf记录了向更高位的借位值

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

11.5 OF标志

检测点11.2

标志寄存器,汇编语言学习笔记,web安全,网络安全

11.6 abc指令

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

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

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

mov ax,2

mov bx,1

sub bx,ax

adc ax,1

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

mov ax,1

add ax,ax

adc ax,3

执行后(ax)=5,相当于执行(ax)+3+CF=2+3+0=5

mov al,98H

add al,al

adx al,3

执行后 (al)=34H,相当于执行(ax)+3+CF=30H+3+1=34H

adc指令前面的指令,决定在执行adc指令的时候加上的CF的值的含义。也就是说关键在于所加上的CF值是被什么指令设置的。如果CF的值是被sub指令设置的,那么它的含义就是借位值;如果是被add指令设置的,那么它的含义就是进位值。

加法运算分两步进行:①低位相加②高位相加加上低位相加产生的进位值。

CPU提供adc指令的目的,就是来进行加法的第二步运算的。adc指令和add指令相配合就可以对更大的数据进行加法运算。

编程:计算1EF000H+201000H,结果存放在AX(16)BX(16)中。

mov ax,001EH

mov bx,0F000H

add bx,1000H

adc ax,0020H

编程:1EF0001000H+2010001EF0H,结果存放在AX(16)BX(16)中和cx(16)

计算分三步进行:

(1)先将低16位相加,完成后,CF中记录本次相加的进位值。

(2)再将次高16位和CF(来自低16位的进位值)相加,完成后,CF中记录本次相加的进位值。

(3)最后高16位和CF(来自次高16位的进位值)相加,完成后,CF中记录本次相加的进位值。

mov ax,001EH

mov bx,0F000H

mov cx,1000H

add cx,1EF0H

add bx,1000H

adc ax,0020H

编程:对两个128位数据进行相加

assume cs:code,ds:data

    data segment

            db 16 dup(88H)

            db 16 dup(11H)

    data ends

    code segment

    start:

            mov ax,data

            mov ds,ax

            mov si,0

            mov di,16

            mov cx,8

            call add128

            mov ax,4C00H

            int 21H

    add128:

            push ax

            push cx

            push si

            push di

            sub ax,ax;CF设置为0

        s:

            mov ax,[si]

            adc ax,[di]

            mov [si],ax

            inc si;不能用add si,2代替

            inc si;因为会影响cf

            inc di;loopinc不会影响

            inc di

            loop s

             pop di

             pop si

             pop cx

             pop ax

             ret

    code ends

end start

11.7 sbb指令

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

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

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

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

sbbadc是基于同样的思想设计的两条指令,在应用思路上sbbadc类似。

编程:计算003E1000H-00202000H,结果放在ax,bx

mov bx,1000H

mov ax,003EH

sub bx,2000H

sbb ax,0020H

11.8 cmp指令

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

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

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

cmp指令运算执行后通过做减法将对标志寄存器产生影响,其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

cmp ax,ax

执行后结果为0ZF=1,PF=1,SF=0,CF=0,OF=0

mov ax,8

mov bx,3

cmp ax,bx

执行后axbx的值不变,ZF=0,PF=1,SF=0,CF=0,OF=0

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

 cmp ax,bx

标志寄存器,汇编语言学习笔记,web安全,网络安全

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

标志寄存器,汇编语言学习笔记,web安全,网络安全

CPU在执行cmp指令时也包含进行无符号数运算和进行有符号数运算两种含义,所以利用cmp指令可以对无符号数进行比较也可以对有符号数进行比较。

单纯地考察SF的值不可能知道结果的正负。因为SF记录的只是可以在计算机中存放的相应位数的结果的正负(例如:add ah,al执行后,sf记录的是ah中的8位二进制信息所表示的数据的正负)

以cmp ah,bh为例,总结一下CPU执行cmp指令后,sf和of的值是如何来说明比较的结果的:

1、如果SF=1SF=0OF=0,逻辑上真正结果的正负=实际结果的正负。

of=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负;

若sf=1,实际结果为负,所以逻辑上真正的结果为负,所以(ah)<(bh)

若sf=0,实际结果非负,所以逻辑上真正的结果非负,所以(ah)≥(bh)

2、如果SF=1SF=0OF=1,逻辑上真正结果的负正≠实际结果的正负。

of=1,说明有溢出,逻辑上真正结果的正负≠实际结果的正负;

若sf=1,实际结果为负,而又有溢出,这说明是由于溢出导致了实际结果为负,简单分析一下,就可以看出,如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正,则说明(ah)>(bh)。

若sf=0,实际结果非负,而of=1说明有溢出,则结果非0,所以,实际结果为正。实际结果为正,而又有溢出,这说明是由于溢出导致了导致了实际结果非负,简单分析一下就可以看出,如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负,则说明(ah)<(bh)。

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

cmp相配使用,根据cmp指令的比较结果(cmp指令执行后相关标志位的值)进行工作的指令。

cmp指令可以同时进行两种比较,无符号数比较和有符号数比较,所以根据cmp指令的比较结果进行转移的指令也分为两种:

(1)根据无符号数的比较结果进行转移的条件转移指令,它们检测ZFCF的值;

根据有符号数的比较结果进行转移的条件转移指令,它们检测SFOFZF的值。

它们所检测的标志位都是cmp指令进行无符号数比较时候记录比较结果的标志位。

指令

含义

检测的相关标志位

je

等于则转移

ZF=1

jne

不等于则转移

ZF=0

jb

低于则转移

CF=1

jnb

不低于则转移

CF=0

ja

高于则转移

CF=0 and ZF=0

jna

不高于则转移

CF=1 or ZF=1

j

e

ne

b

nb

a

na

jump

equal

not equal

below

not below

above

not above

编程:如果(ah)=(bh)则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)。

cmp ah,bh

je s                       ;ZF=1则跳转

add ah,bh

jmp short ok

    s: add ah,bh

   ok: ret 

je检测的是ZF的位置,不管je前面是什么指令,只要CPU执行je指令时,ZF=1那么就发生转移。

        mov ax,0

        mov ax,0

        je s

        inc ax

    s:

        inc ax

 执行后(ax)=1,add ax,0使得ZF=1,所以je指令将进行转移。 

编程:统计data段中数值为8的字节的个数,用ax保存统计结果。

方案一

assume cs:code

    data segment

            db 8,11,8,1,8,5,63,38

    data ends

    code segment

    start:

            mov ax,data

            mov ds,ax

            mov bx,0;ds:bx指向第一个字节

            mov ax,0;初始化累加器

            mov cx,0

        s:

            cmp byte ptr [bx],8;8进行比较

            jne next;如果不相等转到next,继续循环

            inc ax;如果相等就计数值加1

        next:

            inc bx

            loop s;执行后:(ax)=3

            mov ax,4c00h

            int 21h

    code ends

end segment

 方案二

assume cs:code

    data segment

            db 8,11,8,1,8,5,63,38

    data ends

    code segment

    start:

            mov ax,data

            mov ds,ax

            mov bx,0;ds:bx指向第一个字节

            mov ax,0;初始化累加器

            mov cx,0

        s:

            cmp byte ptr [bx],8;8进行比较

            je ok;如果不相等转到ok,继续循环

            jmp short next;如果不想等就转到next,继续循环

        ok:

            inc ax;如果相等就计数值加1

        next:

            inc bx

            loop s;执行后:(ax)=3

            mov ax,4c00h

            int 21h

    code ends

end segment 

编程:统计data段中数值大于8的字节的个数,用ax保存统计结果。

assume cs:code

    data segment

            db 8,11,8,1,8,5,63,38

    data ends

    code segment

    start:

            mov ax,data

            mov ds,ax

            mov bx,0;ds:bx指向第一个字节

            mov ax,0;初始化累加器

            mov cx,0

        s:

            cmp byte ptr [bx],8;8进行比较

            jna next;如果大于8转到next,继续循环

            inc ax;如果大于就计数值加1

        next:

            inc bx

            loop s;执行后:(ax)=3

            mov ax,4c00h

            int 21h

    code ends

end segment

检测点11.3

标志寄存器,汇编语言学习笔记,web安全,网络安全

11.10 DF标志和串传送指令

1、DF标志

flag的第10位是DF,方向标志位。

在串处理指令中,控制每次操作后si(一般指向原始偏移地址)di(一般指向目标偏移地址)的增减。

DF=0:每次操作后sidi递增;

DF=1:每次操作后sodi递减。

2、串传送指令

movsb(mov string byte)串传送指令

以字节为单位传送

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

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

movsw

以字为单位传送。

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

movsbmovsw进行的是串传送操作中的一个步骤,一般和rep配合使用,格式:rep movsbrep的作用是根据cx 的值,重复执行后面的串传送指令。由于每执行一次movsb指令sidi都会递增或递减指向后一个单元或前个单元,则rep movsb就可以循环实现(cx)个字符的传送。

使用串传送指令进行数据的传送,需要提供:

1、传送的原始位置;

2、传送的目的位置;

3、传送的长度;

4、传送的方向。

由于flagDF位决定着串传送指令执行后,sidi改变的方向,8086CPU提供两条指令对DF位进行设置:

(1)cld指令:将标志寄存器的DF位设置为0

(2)std指令:将标志寄存器的DF位设置为1

11.11 pushf和popf

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

pushfpopf为直接访问标志寄存器提供了一种方法。

下面的程序执行后ax的值是多少?

mov ax,0

push ax

popf

mov ax,0fff0h

add ax,0010h

pushf

pop ax

and al,11000101b

and ah,00001000b

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

标志寄存器,汇编语言学习笔记,web安全,网络安全文章来源地址https://www.toymoban.com/news/detail-728558.html

到了这里,关于汇编语言——第11章 标志寄存器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Arm汇编---寄存器

    寄存器:r0~r15, sp, lr, sb, sl, fp, ip, pc 条件码:eq, ne, hs, lo, mi, pl, vs, vc, hi, ls, ge, lt, gt, le, al ------------------------------------------ 一、数据寄存器 --------------------------------------------- ------------------------------------------ 二、指针寄存器 --------------------------------------------- --------------------

    2024年02月02日
    浏览(44)
  • 16位汇编通用寄存器

    1、输入命名debug,进入调试程序 2、r 命令显示寄存器 3、a命令输入汇编指令 4、t命令单步执行汇编指令 5.数据溢出后标志位NC 变为NY, 0变成1 最后A

    2023年04月11日
    浏览(58)
  • 通用寄存器-汇编复习(1)

    弄清寄存器表达,原理和配件及汇编实验验证。 8086cpu寄存器,字在寄存器存储 往期文章: 汇编语言基础-汇编复习(0)_luozhonghua2000的博客-CSDN博客 一个典型的 CPU(此处讨论的不是某一具体的 CPU)由运算器、控制器、寄存器(CPU工作原理)等器件构成,这些器件靠内部总线相连。前

    2024年02月07日
    浏览(45)
  • ARM汇编寄存器和常用指令详解

    对于32位及其以下的ARM处理器来说,函数调用规则如下: 父函数与子函数的入口参数以此通过 R0~R3 这4个寄存器传递。 父函数在调用子函数前先将子函数入口参数存入 R0~R3 寄存器中,若只有一个入口参数则使用 R0 寄存器传递,若有2个入口参数则使用 R0 和 R1 寄存器传递,以

    2024年02月03日
    浏览(50)
  • ARM64 寄存器、常用汇编指令收集

    ARM64 有34个寄存器,包括31个通用寄存器、SP、PC、CPSR。 寄存器 位数 描述 x0-x30 64bit 通用寄存器,如果有需要可以当做32bit使用:WO-W30 FP(x29) 64bit 保存栈帧地址(栈底指针) LR(x30) 64bit 通常称X30为程序链接寄存器,保存子程序结束后需要执行的下一条指令 SP 64bit 保存栈指针,使用

    2023年04月20日
    浏览(40)
  • 一、1.汇编指令、寄存器和寻址方式

    立即数:可以立即在一条机器指令后找到具体数值的数,如内存中00位写着加指令,01位写着1100_1111,意思就是将1100_1111(十进制207)加到某处,反之可以表示数据的地址。 低端字节序:16位寄存器数据存入内存(内存单位为8位),寄存器低位存入内存低位(如00)高位存入内

    2024年02月14日
    浏览(51)
  • [ARM 汇编]高级部分—系统控制协处理器—3.2.3 控制寄存器的读写操作

    在这一部分,我们将学习如何使用ARM汇编指令在系统控制协处理器(CP15)的控制寄存器上执行读写操作。我们将通过实例来讲解如何使用MCR(Move to Coprocessor Register)和MRC(Move from Coprocessor Register)指令进行读写操作。 MCR指令 MCR指令用于将ARM内核寄存器的值写入协处理器寄存

    2024年02月11日
    浏览(57)
  • 【C语言】理解最快的关键字:register 和 寄存器的地位

    register int a = 10; 被register修饰的变量会被***建议***存放在寄存器中,但只是建议,主要还是由操作系统决定。 寄存器是一种造价很高、读写速度很快的存储设备。 存储设备 空间大小 寄存器(regs) 4byte,CPU通常集成几十个寄存器 高速缓存(cache) 128M,CPU通常集成集成多个高

    2024年02月06日
    浏览(48)
  • Verilog语言中的线型wire变量与寄存器类型reg变量讲解

    (1)创建wire线型 (2)在always块中要赋值的不能是wire类型,只能是reg类型 (3)输入类型不能是reg类型 (4)输出reg类型,但没有触发条件时,软件会自动将触发器综合掉

    2024年02月16日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包