滴水三期:day04.3-标志寄存器
一、标志寄存器总览
EFLAGS寄存器,主要用于反映处理器的状态和ALU运算结果的某些特征及控制指令的执行。通俗来说:标志寄存器与CPU中的其他寄存器不一样:它是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息
那么标志寄存器有哪些:
标志寄存器是32位的寄存器,每一位都有专门的含义,比如第一位叫CF是进位标志(有1和0两种情况),第二位永远都是1,第三位叫PF是奇偶标志位(有1和0两种情况)等等。最常用的几个标志位一定要记住名称、含义以及在第几位:CF,PF,AF,ZF,SF,OF
OD中标志寄存器怎么查看:
也在寄存器区域,OD已经帮我们把标志寄存器的32位拆分好了,C就是表示CF,P就表示PF,等等。最下面的EFL就表示标志寄存器,用十六位表示32位数。有些软件如果没有帮我们拆分成各个标志位,则我们需要自己会把十六进制表示的标志寄存器中的值化成32位二进制数,然后去对应的位上找标志
二、标志寄存器常用的标志
1.进位标志CF
进位标志CF(Carry Flag):如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。
最高位为多少取决于做运算的数据宽度,比如
add eax,0x1
由于最终结果存到eax中,eax是32位,所以结果的最高位就为32位,如果运算结果超过了32位,那么结果取低32位,高位舍弃,并且CF为1。又比如add al,0xff
,如果运算结果超过8位,则将高位舍弃只取低8位,那么由于最高位产生了进位,CD为1sub 0x80,0x81 #CF=1
2.奇偶标志PF
奇偶标志PF(Parity Flag):运算结果的==低八位==中,1 的个数为偶数时置 1,否则置 0。只看低八位,不管数据宽度是多少
ADD AL,3
,也是看结果化成8位2进制,有几个1;而mov al,3
,不属于运算,不会影响标志寄存器
3.辅助进位标志AF
辅助进位标志AF(Auxiliary Carry Flag):在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
在字节操作时,发生低4位向高4位进位或借位时
比如:某寄存器中的值0x4F做操作时最后运算结果右往左第一个F发生了进位或者借位,则AF为1
在字操作时,发生低字节向高字节进位或借位时
比如:某寄存器中的值0x01FF做操作时最后运算结果右往左第二个F发生了进位或者借位,则AF为1
在双字操作时,发生低字向高字进位或借位时
比如:某寄存器中的值0x0100FFFF做操作时最后运算结果从右往左第四个F发生了进位或者借位,则AF为1
上述为海东老师讲述的,自己验证时发现错误,实验为:无论数据宽度,只看低第4位是否发生进位或借位
4.零标志ZF
零标志ZF(Zero Flag):零标志ZF用来反映运算结果是否为0,如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位
比如
xor eax,eax
,表示eax清零,则此时ZF值为1。注意一定是运算结果,如果mov eax,0
则不会影响ZF
5.符号标志SF
符号标志SF(Sign Flag):符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同
还是注意mov指令不改变标志寄存器,而且要注意数据宽度,最高位由数据宽短决定
注意如果SF位为1,只能说明最高位为1,不能说明这就一定是一个负数,因为有符号数和无符号数是程序员在写的时候自己决定的,所以当程序员认为结果为无符号数时,那么最高位是1也不是负数,除非认为是有符号数,才能根据SF位为1判断是结果是负数
6.溢出标志OF
溢出标志OF(Overflow Flag):溢出标志OF用于反映有符号数加减运算所得结果是否溢出,如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0(溢出主要是给有符号运算使用的)
口诀:若同符号数相加,而结果符号与之相反,则OF=1,否则OF=0;若不同符号相加,一定没有溢出;若被减数与减数异号,而结果的符号与减数相同,则OF=1,否则OF=0
计算机是怎么判断OF是否溢出:
比如现在计算机运算 80H - 40H mov al,80 sub al,40计算机遇到减法,实际上是按照加法来做的:相当于 mov al,80 add al,c0 #计算机将-40H化成c0H1000 0000 1100 0000 ----------- 计算中,符号位有进位,则取1 最高有效位(比符号位的低一位)向符号位产生的进位没有,则取0 做异或:1 xor 0 == 1 所以计算机才会将OF位置为1
7.方向标志DF
方向标志DF(direction Flags):当该位置1时(DF=1),存储器地址自动减少(减多少一般看指令给的宽度是byte,word还是dword,或者视情况而定),串操作指令为自动减量指令,即从高位到低位处理字符串;当该位置0时(DF=0),存储器地址自动增加,串操作指令为自动增量指令
举例详见MOVS和STOS指令
三、CF最高位进位与OF溢出区别
- 总结:进位标志CF表示无符号数运算结果是否超出范围;溢出标志OF表示有符号数运算结果是否超出范围。简单来说就是如果你把做运算的数当成无符号数则判断是否溢出(进位)看CF位;如果你把做运算的数当成有符号数则判断是否溢出看OF位
1.CF最高位进位
- 什么是CF最高位进位:计算机中存储的数是有符号数还是无符号数,是我们来决定的,计算机只是负责存储这个数。当我们把做运算的数当成无符号数时,如果数据宽度为8位,则当某寄存器的值运算后的结果大于0xFF,则表示溢出,CF置为1;如果数据宽度为16位,则当某寄存器的值运算后的结果大于0xFFFF,则表示溢出(最高位进位),CF置为1;如果数据宽度为32位,则当某寄存器的值运算后结果大于0xFFFFFFFF,则表示溢出(最高位进位),CF置为1
- 所以如果我们如果把运算的数当成无符号数,则做完运算后想知道结果有没有溢出(最高位进位),则只用看CF位即可,不要关注OF
2.OF溢出
还记得数据宽度表示图嘛:如果数据宽度为8位,且我们认为数为无符号数时,则0到FF都表示正数;如果我们认为数为有符号数,则正数为从0到7F,负数为从FF到80(FF为最大的负数-1,从FF到80表示的负数依次减小)。同理如果数据宽度为16位,且认为是无符号数,则从0到FFFF都表示正数;如果我们认为是有符号数,则正数为从0到7FFF,负数为从FFFF到8000
什么是OF溢出:溢出主要是给有符号运算使用的,如果我们把做运算的数当成有符号数时(以下说明:由于计算机会把减法当做加一个负数来处理,所以下面说明的情况中只会涉及加法运算)
- 当数据宽度为8位
两个正数(0x0到0x7F)做加运算,如果结果是负数,即结果超过了7F,则表示溢出,OF置为1
比如现在两个正数0x13+0x5b=0x6e,没有超过正数的范围(0x0到0x7F),则没有溢出
现在两个正数0x40+0x7F=0xBF,超过了正数的范围,则溢出
两个负数(0xFF到0x80)做加运算,如果结果为正数,即低8位表示的数在正数那个半球(0x00到0x7F),则表示溢出,OF置为1
比如现在两个负数0xFF+0xC0=0x1BF,由于数据宽度为8位,高位舍弃取低8位,结果为0xBF,没有超过负数的范围(0xFF到0x80),则没有溢出
现在有两个负数0xA8+0x81=0x129,取低8位,结果为0x29,超过了负数的范围(0xFF到0x80),溢出
当数据宽度为16位
- 两个正数(0x0到0x7FFF)做加运算,如果结果为负数,即结果超过了7FFF,则表示溢出,OF置为1
- 两个负数(0xFFFF到0x8000)做加运算,如果结果为正数,即低16位表示的数在正数那个半球(0x0000到0x7FFF),则表示溢出,OF置为1
当数据宽度为32位
- 两个正数(0x0到0x7FFFFFFF)做加运算,如果结果为负数,即结果超过了7FFFFFFF,则表示溢出,OF置为1
- 两个负数(0xFFFFFFFF到0x80000000)做加运算,如果结果为正数,即低32位表示的数在正数那个半球(0x00000000到0x7FFFFFFF),则表示溢出,OF置为1
- 当数据宽度为8位
记住:正 + 负 永远都不会有溢出
原因:比如现在两个数0xC0+0x3F=0xFF,由于我们知道0xC0的绝对值大于0x3F,而且0xC0为负数,0x3F为正数(其实所有负数绝对值都大于正数按照数据宽度为8位来说),所以结果为负数,而结果0xFF也没有超过负数的范围(0xFF到0x80),所以没有溢出;再比如所以负数和正数相加,如果结果为正,那必定小于相加前那个正数,同理,若结果为负,必定大于相加前那个负数,不论哪种情况,结果都不可能超出可表示的最小负数和最大正数之间的范围
练习举例:
无符号、有符号都不溢出
MOV AL,8 ADD AL,8
无符号溢出、有符号不溢出
MOV AL,0xFF ADD AL,2
无符号不溢出、有符号溢出
MOV AL,7F ADD AL,2
无符号、有符号都溢出
MOV AL,0xFE ADD AL,80
现在肯定有一个疑问:有符号数,一个负数和一个负数相加,结果可能溢出可能不溢出:如果溢出:则结果应该在右半球,但是右半球不是表示正数吗??现实生活中,两个负数相加怎么可能结果为正呢???就是因为发生了溢出!!计算机不管你现实生活中两个负数相加结果一定是正数,计算机认不到有没有符号!!计算机只负责对二进制数做运算,算出来结果是多少就是多少。正因为如此,如果两个负数相加0x8fffffff+0xaaaa4444结果应该为0x1 3AAA 4443,但是现在由于有数据宽度,则结果只能取低8位,那么结果就为0x3AAA4443,这个数在左半球,所以溢出了,而且由于数据宽度的限制,则结果并不是正常的相加的结果,这就解释了上面的原因,这种现象是正常的
滴水三期:day04.3-标志寄存器相关推荐
- 滴水三期逆向基础系列(一)-读取文件到内存再读取回文件
跟着滴水三期学了很长时间了,本着,每一点都要吃透的精神,跟"读文件到内存(拉伸),再读回文件(压缩回来)"杠了一天.先看看按着老师的架构写的代码吧(老师的代码有很多问题(可能是我太 ...
- 一个奇葩的标志寄存器 flag寄存器
注意: mov,push,pop等传送指令,执行结果对标志寄存器并无影响! ZF标志:结果为0,则ZF为1:不为0,ZF为0:(zero flag) PF标志:如果1的个数为偶数,pf=1:如果为奇数 ...
- 标志寄存器的详细解释
简介: CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有三种作用. (1)用来存储相关指令的某些执行结果. (2)用来为CPU执行相关指令提供行 ...
- 汇编语言随笔(3)-条件转移指令和标志寄存器
标志寄存器 标志寄存器通常具有以下三种作用: 1,用来存储相关指令的某些执行效果 2,用来为CPU执行相关指令提供行为依据 3,用来控制CPU的相关工作方式 ...
- 汇编语言--标志寄存器
标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作用. 用来存储相关指令的某些执行结果: 用来为CPU执行相关指令提供行为依据: 用 ...
- 8086汇编复习3 - 标志寄存器 - 使用emu8086
1 认识标志寄存器 标志寄存器 CPU内部有一种寄存器,具有三种作用: 1)存储相关指令的某些执行结果: 2)用来为CPU执行相关指令提供行为依据: 3) 用来控制CP ...
- 汇编中的通用寄存器、标志寄存器、段寄存器
通用寄存器: 寄存器和变量差不多,目的都是用于保存一些即将操作的数据 EAX(accumulator) 寄存器:扩展累加寄存器(一般在乘/除中会被主动调用),也可以用于其他用途 ECX(Count) ...
- 《汇编语言(第三版)》pushf 和 popf 指令,以及标志寄存器在 Debug 中的表示
pushf 和 popf pushf 的功能是将标志寄存器的值压栈,而 popf 是从栈中探出数据,输入标志寄存器. pushf 和 popf,为直接访问寄存器提供了方法. 格式 pushf popf ...
- 《汇编语言(第三版)》标志寄存器
标志寄存器 8086CPU中的flag寄存器包括: CF.PF.ZF.SF.OF.DF. 传送指令不影响标志寄存器 ZF标志寄存器 zf标志寄存器位于flag中的第6为,表示零标志位.(至于flag是 ...
最新文章
- hadoop中NameNode、DataNode和Client三者之间协作关系及通信方式介绍
- 如何快速融入一家公司
- 操作系统上机作业--多线程排序
- 移动开发day1_过渡_2d转换_3d立体
- 一款非常好看的雷姆背景的时间单页(附雷姆图片)
- PHP全路径无限分类导航LINK代码实现
- android 两个视频合并,手机如何合并视频片段 安卓手机多个视频合并成一个的方法...
- 那些不得不提的坑(持续添加中)
- Apache Shiro官方构架文档中文翻译
- Excel连接数据库
- 网页上直接sql查询操作数据库,并在网页上展示列表数据的工具页面
- python朋友圈点赞统计_微信公众号所有历史文章的标题/点赞数/阅读数统计
- java中try-catch-finally的使用
- 【办公协作软件】万彩办公大师教程丨全能文档转换工具
- Java的在哪里找labor_LaborDay哪里玩
- 解决思科 Cisco Packet Tracer 7.3登录问题
- 海外疫情公共信息服务平台
- linux下查大文件的方法
- 报错: Called “net usershare info“ but it failed
- Redis 全实践(超长文预警)