[汇编语言]标志寄存器
目录
- 一、ZF标志
- 二、PF标志
- 三、SF标志
- 四、CF标志
- 五、OF标志
- 六、adc指令
- 七、sbb指令
- 八、cmp指令
- 九、检测比较结果的条件转移指令
- 十、DF标志和串传送指令
- 十一、pushf和popf
CPU内部的寄存器中,有一种特殊的寄存器,具有以下3种作用
- 用来存储相关指令的某些执行结果
- 用来为CPU执行相关指令提供行为依据
- 用来控制CPU的相关工作方式
这种特殊的寄存器在8086CPU中,被称为标志寄存器,8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW),我们已经使用过8086CPU的ax、bx、cx、dx、si、di等13个寄存器,本章中的标志寄存器(flag)是最后一个寄存器
flag和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义,但是flag寄存器是按位来起作用的,也就是说每一位都有专门的含义,记录特定的信息:
flag的1、3、5、12、13、14、15位在8086CPU中没有使用,不具有任何含义,而其他位都具有特殊的含义
这一章中,我们学习相关标志位以及典型指令
一、ZF标志
flag的第6位是ZF,零标志位。它记录相关指令执行后,其结果是否为0。如果结果为0,那么ZF = 1;结果不为0,ZF = 0
比如指令
mov ax,1
sub ax,1
执行后,结果为0,ZF = 1
mov ax,2
sub ax,1
执行后,结果不为0,ZF = 0
二、PF标志
flag的第2位是PF,奇偶标志位,它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数,如果为偶数pf = 1,奇数pf = 0
mov al,1
add al,10
执行后,结果为00001011B,其中奇数个1(3个),所以pf = 0
三、SF标志
flag的第7位是SF,符号标志位,它记录相关指令执行后,其结果是否为负。如果结果为负,SF = 1;结果非否,SF = 0。
10000001B可以看作是无符号数129,也可以看作是有符号数-127
四、CF标志
flag的第0位是CF,进位标志位。一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值或是借位值(减法就是借位)
mov al,98H
add al,al ;执行后,(al)=30H,CF = 1,CF记录了从最高位有效位向更高位的进位值
add al,al ;执行后,(al)=60H,CF = 0,CF记录了从最高位有效位向更高位的进位值
五、OF标志
如果超出了机器所能表示的范围称为溢出。
那么什么是机器所能表示的范围呢?
比如说,指令运算的结果用8位寄存器或是内存单元来存放,比如add al,3,那么对于8位的有符号数据,机器所能表示的范围就是-128 ~ 127,同理,对于16位有符号数据,机器所能表示的范围就是-32768 ~ 32767
如果运算结果超出了机器所能表达的范围,将产生溢出
这里所讲到的溢出只是对有符号数运算而言。下面看两个溢出的例子:
mov al,98
add al,99
执行后将产生溢出,因为add al,99的有符号数运算是:(al)=(al)+99 = 99 + 98 = 197,结果197超过了8位有符号的范围
因为进行的是有符号数运算,所以al中存储的是有符号数,而C5H是由符号数-59的补码,如果我们用add指令进行的是有符号数运算,则99 + 98 = -59这样子的结果是无法接受的,造成这种情况的原因实际上对应的结果是197,为一个由符号数,在8位寄存器al中存放不下。
由于在进行有符号数运算时,可能会发生溢出而造成严重的结果错误。则CPU需要对指令执行后是否产生溢出进行记录。flag的第11位是OF,溢出标志位,一般情况下,OF记录了有符号数运算的结果是否发生了溢出。如果发生了溢出,则OF = 1,如果没有CF = 0
CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位。
比如:
mov al,98
add al,99
add指令执行后,CF = 0,OF = 1,CPU在执行add等指令的时候就包含了两种含义:无符号数和有符号数的运算。对于无符号数运算,CPU用CF位来记录是否产生了进位;对于有符号数来说,用OF来记录是否产生了进位,当然还有CF来记录有结果的符号。对于无符号运算,99+98没有进位,CF=0,对于有符号数的运算,99+98发生了溢出,OF=1
六、adc指令
adc是带进位加法指令,它利用了CF位上记录的进位值。
指令格式:adc 操作对象1,操作对象2
功能:操作对象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,执行的时候相当于是计算:(ax)+1+CF = 2 + 1 + 1
可以看出,adc指令比add指令多加了一个CF位的值。
为什么CPU要提供这样一条指令?
在执行adc指令的时候加上CF值的含义是由adc指令前面的指令所决定的,也就是说,关键在于所加上的CF值被什么指令设置的。显然,如果CF的值是被sub指令设置的,那么它的含义加上借位值,如果是被add指令设置的,它的含义就是进位值
下面的指令和add ax,bx具有相同的结果:
add al,bl
adc ah,bh
看来CPU提供adc指令的目的就是用来进行加法的第二部运算的。adc指令和add指令相配合就可以对更大的数据进行加法运算。
编程,计算1EF000H+201000H,结果存在ax(高16位)bx(低16)
因为两个数据的位数都大于16,用add指令无法进行计算。我们将计算分两步进行,先将低16位相加,然后将高16位和进位值相加。
mov ax,001EH
mov bx,0F000H
add bx,1000H
adc ax,0020H
adc指令执行后,可能产生进位值,所以也会对CF位进行设置。由于有这样的功能,我们就可以对任意大的数据进行加法运算
编程,计算1EF0001000H+2010001EF0H,结果存在ax(最高16位)bx(次高16位)cx(低16位)
- 先将低16位进行相加,完成后,CF记录本次相加的进位值
- 然后将次高16位和CF相加,完成后CF记录本次进位
- 最高16位和CF相加,完成后,CF中记录本次相加的进位值
mov ax,001EH
mov bx,0F000H
mov cx,1000H
add cx,1EF0H
adc bx,1000H
adc ax,0020H
七、sbb指令
sbb是带借位减法指令,它利用了CF位上记录的借位值
指令格式:sbb 操作对象1,操作对象2
功能:操作对象1 = 操作对象1 - 操作对象2 - CF
比如指令:sub ax,bx实现的是:(ax)=(ax)-(bx)-CF
sbb指令执行后,要对CF进行设置,利用sbb指令可以对任意大的数据进行减法运算。比如计算003E1000H-00202000H,结果存在ax、bx中
程序如下:
mov bx,1000H
mov ax,003Eh
sub bx,2000H
sbb ax,0020H
八、cmp指令
cmp是比较指令,cmp的功能相当于是减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器来得知比较结果。
cmp 指令格式:cmp 操作对象1,操作对象2
功能:计算操作对象1 - 操作对象2,但不保存结果,仅仅根据计算结果对标志寄存器来进行设置
比如:指令cmp ax,ax,做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅影响flag的相关各位。——比如看借不借位,结果为不为0决定了CF和ZF
cmp ah,bh
如果(ah)=(bh),则(ah)-(bh) = 0,所以zf = 1
如果(ah)≠(bh),则(ah)-(bh) ≠ 0,所以zf = 0
所以可以根据cmp指令执行后的zf值,就可以判断两个数据是否相等
对于有符号数,(ah)< (bh)的情况下,(ah)-(bh)可能会引起sf = 1,即结果为负。但是结果为负不一定说明(ah)<(bh),比如(ah)-(bh) = 34 - (-96) = 82H,82H是-126的补码,所以sf = 1
九、检测比较结果的条件转移指令
转移指的是他可以修改IP,而条件指的是他可以根据某种条件,决定是否修改IP
比如,jcxz就是一个条件转移指令,他可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做。所有条件转移位移都是-128 ~ 127
除了jcxz外,CPU还提供了其他条件转移指令,大多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP。他们检测的是哪些标志位?他们检测的都是哪些标志位?
下面是常用的根据无符号数的比较结果进行转移的条件转移指令:
指令 | 含义 | 检测的相关标志位 |
---|---|---|
je | 等于则转移 | zf = 1 |
jne | 不等于则转移 | zf = 0 |
jb | 低于则转移 | cf = 1 |
jnb | 不低于则转移 | cf = 0 |
ja | 高于则转移 | cf = 0且zf = 0 |
jna | 不高于则转移 | cf = 1或zf = 1 |
e表示equal
ne表示not equal
b表示below
nb表示not below
a表示above
na表示not above
这些都是cmp指令进行无符号数比较的时候,记录比较结果的标志位,比如je,检测zf位,当zf = 1的时候,进行转移,如果在je前面使用了cmp指令,那么je对zf的检测实际上就是间接的堆cmp比较结果。
编程实现如下功能:如果(ah)=(bh)则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)
cmp ah,bh
je s
add ah,bj;否则的情况
jmp short ok
s:add ah,ah
ok:...
十、DF标志和串传送指令
flag的第十位是DF,方向标志位。在串处理指令中,控制每次操作后si和di的增减
df = 0,每次操作后si、di递增
df = 1,每次操作后si、di递减
下面看一个串传送指令:
格式:movsb
功能:执行movsb相当于进行下面几步操作:
- ((es)*16+(di)) = ((ds)*16+(si))
- 如果df = 0,则(si)=(si)+1,(di)=(di)+1;如果df = 1,则相应减1
汇编语言描述movsb功能如下:
``mov es:[di],byte ptr ds:[si] ;可以看作底层是这样子写
如果df = 0
inc si
inc di
如果df = 1
dec si
dec di
可以看出,movsb的功能是将ds:si指向的内存单元中的字节送入es:di,然后根据df的值,将si和di+1或是-1
当然也可以传送一个字:
格式:mov sw
mov es:[di],word ptr ds:[si]
;可以看作底层是这样子写
如果df = 0
add si,2
add di,2
如果df = 1
sub si,2
sub di,2
movsb和movsw进行的是串传送操作的一个步骤,一般来说,movsb和movsw都是和rep配合使用,格式如下:
rep movsb
用汇编语法来描述rep movsb的功能就是:
s: movsb
loop s
可以看出,rep的作用是根据cx,重复执行后面的串传送指令。由于每执行依次movsb指令si和di都会递增或是递减指向后一个单元或是前一个单元。则rep movsb就可以循环实现(cx)个字符的传送
同理,也可以使用这样子的指令:rep movsw
相当于是:
s: movsw
loop s
由于flag的df位决定着串传送指令执行后,si和di改变的方向,所以CPU应该提供相应的指令来对df位进行设置,从而使程序员能够决定传送的方向。
8086CPU提供下面两条指令对df位进行设置:
cld指令:将标志寄存器的df置为0
std指令:将标志寄存器的df置为1
看下面两个程序:
- 用串传送指令,将data段中的第一个字符串复制到他后面的空间中
data segmentdb 'welcome to masm'db 16 dup(0)
data ends
传送的原始位置:ds:si
传送的目的位置:es:di
传送的长度:cx
传送的方向:df
mov ax,data
mov ds,ax
mov si,0 ;ds:si指向data:0
mov es,ax
mov di,16
mov cx,16
cld
rep movsb
十一、pushf和popf
pushf的功能是将标志寄存器中的值压栈,而popf是从栈中弹出数据,送入标志寄存器中
pushf和popf为直接访问标志寄存器提供了一种方法
[汇编语言]标志寄存器相关推荐
- 汇编语言--标志寄存器
标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作用. 用来存储相关指令的某些执行结果: 用来为CPU执行相关指令提供行为依据: 用 ...
- Win-MASM64汇编语言-标志寄存器(EFLAGS/PSW/PUSHF/POPF)
CPU内部需要一种特殊的寄存器来完成下面三个功能 1.用来存储相关指令的执行结果是否满足某些特性 2.为cpu执行相关指令提供行为依据 3.用来控制cpu的相关工作方式 能完成上面三个功能的寄存器被成 ...
- 汇编语言随笔(3)-条件转移指令和标志寄存器
标志寄存器 标志寄存器通常具有以下三种作用: 1,用来存储相关指令的某些执行效果 2,用来为CPU执行相关指令提供行为依据 3,用来控制CPU的相关工作方式 ...
- 《汇编语言(第三版)》pushf 和 popf 指令,以及标志寄存器在 Debug 中的表示
pushf 和 popf pushf 的功能是将标志寄存器的值压栈,而 popf 是从栈中探出数据,输入标志寄存器. pushf 和 popf,为直接访问寄存器提供了方法. 格式 pushf popf ...
- 《汇编语言(第三版)》标志寄存器
标志寄存器 8086CPU中的flag寄存器包括: CF.PF.ZF.SF.OF.DF. 传送指令不影响标志寄存器 ZF标志寄存器 zf标志寄存器位于flag中的第6为,表示零标志位.(至于flag是 ...
- 汇编语言之标志寄存器
1.标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作 用: 1. 用来存储相关指令的某些执行结果. 2. 用来为CPU执行相关指令提供 ...
- 王爽 汇编语言第三版 第11章 标志寄存器
条件码: ① OF(Overflow Flag)溢出标志,溢出时为1,否则置0.标明一个溢出了的计算,如:结构和目标不匹配. ② SF(Sign Flag)符号标志,结果为负时置1,否则置0. ③ Z ...
- 汇编语言笔记(三): 标志寄存器
章节目录 简介 ZF 标志寄存器 PF 标志寄存器 SF 标志寄存器 CF 标志寄存器 OF 标志寄存器 几条相关指令 DF 标志寄存器 PUSHF and POPF 标志寄存器 作者能力有限, 如果 ...
- 【汇编语言】标志寄存器PSW
简介 8086CPU设置了一个16位标志寄存器PSW(也叫FR). 其中规定了9个标志位,用来存放运算结果特征和控制CPU操作. 反映指令对数据作用之后,结果的状态(不是结果本身).这些状态将控制后续 ...
最新文章
- webpack-dev-server 和webapck --watch的区别
- 什么是java序列化,如何实现java序列化?
- 在SharePoint环境中更换密码
- 【CodeForces - 144C】Anagram Search(尺取,滑窗问题,处理字符串计数)
- oracle表空间如何压缩,Oracle里表空间的压缩
- 线程等待通知 linux,Java 线程协作 wait(等待)与 notiy(通知)
- ASCII表 基本记忆 -- C
- [osg][原创]osg多屏幕显示,会出现透明需要设置的问题
- 基于遥感图像的船舶目标识别技术
- android handler的机制和原理_Android基础(7)—异步消息处理机制 Handler
- APM_ArduCopter源码解析学习(二)——电机库学习
- 操作系统基础知识复习总结
- 关于Pycharm进行pytorch分布式训练代码
- Java中RuntimeException和Exception区别
- tensorboard--曲线图颜色深浅两条线
- 【游戏开发实战】Unity循环复用列表,支持不规则尺寸(对象池 | UGUI | ScrollRect | Demo源码)
- 555-大数据查重-位图算法
- 网页防篡改技术发展趋势
- 在疫情期间微分销商城如何运营
- Voltus任命全球投资者关系负责人
热门文章
- python招聘现状-python招聘现状
- 什么是云平台,云平台的分类和优势有哪些?
- Python:使用PyAV提取视频关键帧
- FHQ_TREAP学习笔记
- HorizontalScrollView 滑动处理
- 输出100内所含5或5的倍数的值(Python)
- 华为鸿蒙战略发布会视频,华为公布鸿蒙手机操作系统开机画面视频
- 关于COM类工厂80070005和8000401a错误分析及解决办法(DCOM)
- 防复制防破解小区门禁梯控升级非联网CPU卡脱机写卡门禁梯控一卡通系统92HID623CPU V5.00操作说明之用户卡加密发卡设置说明
- html网站底部导航栏怎么做,如何设计一个页面的底部导航?