汇编语言-标志寄存器

摘要:
该标志用于存储相关指令的一些执行结果,并为CPU执行相关指令提供行为基础。该标志用于控制CPU的相关工作模式。该标志与其他寄存器不同。标志寄存器的内部结构和功能。ZF标志的第六位是ZF。某些指令的执行影响标志寄存器,而某些指令的运行不影响标志寄存器;CF记录从最高有效位移动到较高位的进位值,
汇编语言-标志寄存器

CPU内部的寄存器中,有一个特殊的寄存器,叫标志寄存器,它具有以下三种作用:

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

flag和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义。
而flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。

标记寄存器内部结构及其功能简介

汇编语言-标志寄存器第1张

汇编语言-标志寄存器第2张


ZF标志

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

代码示范

mov ax,1

sub ax,1

执行后,结果为0,则ZF=1,表示“结果是0”。

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


PF标志

flag的第2位是PF,奇偶标志位。它记录相关指令执行后,其结果的所有二进制位中1的个数是否为偶数。如果1的个数为偶数,PF=1,如果为奇数,那么PF=0。

代码示范

mov al,1

add al,10

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


SF标志

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

代码示范

mov al,10000001B

add al,1

执行后,结果为10000010B,符号位为1,则SF=1


CF标志

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

代码示范

mov al,98H
add al,al          ;执行后,(al) = 30H, CF=1, CF记录了从最高有效位向更高位的进位值
add al,al     ;执行后,(al) = 60H, CF=0, CF记录了从最高有效位向更高位的进位值


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


OF标志

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

一定要注意CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位。

mov al,98
add al,99
add指令执行后:CF=0,OF=1


adc指令

adc 操作对象1,操作对象2

功能:

操作对象1=操作对象1+操作对象2+CF

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

代码示范

mov ax,2

mov bx,1

sub bx,ax

adc ax,1

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


sbb指令

使用方法和adc指令相似


cmp指令

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

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


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

“转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件,决定是否修改IP。

比如:jcxz就是一个条件转移指令,它可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做。

所有条件转移指令的转移位移都是[-128~127]。

除了jcxz之外,CPU还提供了其他条件转移指令,大多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP。

它们检测的是哪些标志位呢?就是被cmp指令影响的那些,表示比较结果的标志位。这些条件转移指令通常都和cmp相配合使用,就好像call和ret指令通常相配合使用一样。

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

  • 根据无符号数的比较结果进行转移的条件转移指令,它们检测ZF、CF的值;
  • 和根据有符号数的比较结果进行了转移的条件转移指令,它们检测SF、OF和ZF的值。

指令介绍:

这里写图片描述

代码示范

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

cmp ah,bh

je s

    add ah,bh
    jmp short ok

s:add ah,ah

ok:

上面的程序执行时,如果(ah)=(bh),则cmp ah,bh 使ZF=1,而je检测ZF是否为1,如果为1,将转移到标号s处执行指令 add ah,ah。这也可以说,cmp比较ah、bh后所得到的相等的结果使得je指令进行转移。从而很好地体现了je指令的逻辑含义,相等则转移。

虽然je的逻辑含义是“相等则转移”,但它实际进行的操作是,ZF=1时则转移。

“相等则转移”这种逻辑含义,是通过和cmp指令配合使用来体现的,因为cmp指令为“ZF=1”赋予了“两数相等”的含义。

至于究竟在je之前使不使用cmp指令,在于我们在安排je检测的是ZF位置,不管je前面是什么指令,只要CPU执行je指令时,ZF=1,那么就会发生转移。

实例介绍

程序功能:将包含任意字符,以0结尾的字符串中的小写字母转变成大写字母

assume cs:code

data segment
    db 'sfsd;++dfasd"fdsafsd_fdfdfdIIIIss',0
data ends

code segment

start:  mov ax,data
    mov ds,ax
    mov si,0
    call letterc

    mov ax,4c00H
    int 21

letterc:
    push ax
    push ds
    push si

s:  
    mov al,ds:[si]
    mov ah,'a'
    cmp al,ah
    jb next
    mov ah,'z'
    cmp al,ah
    ja next

change:     
    and al,11011111B
    mov ds:[si],al

next:
    inc si
loop s

    pop si
    pop ds
    pop ax

code ends
end start

效果图:

汇编语言-标志寄存器第4张


DF标志和串传送指令

DF标记

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

在串处理指令中,控制每操作后si,di的增减。

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

DF相关指令

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

cld指令:将标志寄存器的DF位置0std指令:将标志寄存器的DF位置1


串传送指令

格式: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的功能如下:

mov es:[di],byte ptr ds:[si]           ;8086CPU并不支持这样的指令,这里只是个描述。

如果DF=0inc si
    inc di

如果DF=1dec si
    dec di

rep指令

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

movsb和movsw都和rep配合使用,格式如下:

mov cx,100
rep movsb

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

mov cx,100
s:movsb
loop s


pushf和popf

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

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

免责声明:文章转载自《汇编语言-标志寄存器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇STM32 串口功能 库函数 详解和DMA 串口高级运用(转载)android 启动模式介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java笔记(十五) 并发包

并发包Java中还有一套并发工具包,位于包java.util.concurrent下,里面包括很多易用 且很多高性能的并发开发工具。 一、原子变量和CAS 为什么需要原子变量,因为对于例如count++这种操作,使用 synchronized成本太高了。Java并发包的基本原子变量有: AtomicBoolean、AtomicInteger、AtomitL...

(转载)U-boot启动完全分析

1.1 U-Boot工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 Ø 硬件设备初始化 Ø 加载U-Boot第二阶段代码到RAM空间 Ø 设置好栈 Ø 跳转到第二阶段代码入口 (2)第二阶段的功能 Ø 初始化本阶段使用的硬件设备 Ø 检测系统内存映射 Ø 将内核从Flash读取到RAM中 Ø 为内核设置启动...

获取,标签里面属性的值的方法

获取,标签里面属性的值的方法,(下面是获取a标签里面属性source-data-lazy-img的值 ) soup2 = BeautifulSoup(span.encode('utf-8'), 'html.parser')for img2 in soup2.find_all('img',{"source-data-lazy-img":True}):  pr...

Android 一种非常好用的Android屏幕适配

前言 网上关于屏幕适配的文章已经铺天盖地了,为什么我还要讲?因为网上现在基本都是使用px适配,即每种屏幕分辨率的设备需要定义一套dimens.xml文件。再加上有些手机还有虚拟按键(例如华为),这样就还需要每个有虚拟按键的设备加多一套dimens.xml文件,再加上平板那些你会发现dimens.xml文件所占的体积已经超过2M了!这绝对不是我们想要的。...

Android 属性自定义及使用获取浅析

一、概述 相信你已经知道,Android 可使用 XML 标签语言进行界面的定义。每个标签中有一个一个的属性,这些属性有相应的属性值。例如: <cn.neillee.composedmenu.RotatingArcMenu android: android:layout_width="wrap_content" android:layout_...

纹理映射 【转】

9.4 纹理对象 使用纹理对象来存储纹理数据的步骤: 1) 生成纹理对象名称 2) 将纹理对象绑定到纹理数据(包括图像数据数组和纹理属性), 即创建纹理对象. 3) 如果OpenGL实现高性能纹理工作集, 应检查是否有足够的空间来存储所有的纹理对象. 如没有足够空间, 应设置每个纹理对象的优先级, 以确保最常用的纹理留在工作集中 4) 绑定和重新绑定纹理对...