x86架构下 CF与OF标志位 带符号和无符号运算 详解
针对能够影响OF和CF标志位的指令,一般来说是涉及到数据运算的指令,这里使用add
举例,即不区分有无符号的加法指令,参与运算的数据,从二进制层级去考虑。
CF标志位
对于CF,它是carry flag,进位标志,这个进位,表示的是二进制层次下的进位,例如:
mov al,98h
add al,al
它的运算是
其中,得到的最高一位,会被丢弃,这个也就是进位了!
模拟一下:
这个进位还是很简单的!
如何实现add指令进位时,CF的变化
这个简单,我们只需要记录一下add的结果的假想最高位即可,就是加法器的进位位。
功能层级理解CF & 进位借位
其实我们只需要从功能角度去理解就可以了,不用关注具体如何实现的,因为这可能非常复杂,不过你的确可以简单思考一下。
CF不仅仅记录add
时候的进位,也记录sub
时候的借位,同时如何想使用这个进位或者借位,还有sbb
,add
等指令。
考虑借位的时候,只需要CF的结果等于加法器进位异或sub即可。
OF标志位
overflow flag,溢出标志位,它记录的不是二进制下的进位,而是十进制下的不合理结果,例如
- 正数 + 正数 = 负数
- 负数 + 负数 = 正数
- ……
我们举个例子,分别从二进制和十进制下看待这个问题。
mov al,98
add al,99
- 从十进制角度,98 + 99 = 197,但是对于8位补码,数据范围是
-128 - 127
,197是不合理的,它溢出了,因此OF 置 1
。 - 从二进制角度,
98 + 99 = 62h + 63h = c5h
,我们可以看到,单从计算机世界来说,两数相加,结果并没有进位,因此CF = 0
我们可以看到,从二进制世界来说,可以很容易识别出进位,但是不容易识别出溢出,因为溢出的规则,是由人类世界的十进制法则决定的,要想实现识别,应该单独设定一些其他逻辑。
因此,我们要联合人类世界和计算机世界,来思考如何实现OF标志位的逻辑。
OF标志置位复位的实现
我们先考虑一下可能溢出的场景(8位二进制补码真值范围 -128 ~ 127)
- 负数 + 负数 = 正数
- 正数 + 正数 = 负数
- 其他…
我们就先假定至于这两种场景吧,那么如何实现OF的逻辑?很简单,列真值表!
我们规定输入
- 操作数1为正数记为0,负数记为1(其实就是最高位)
- 运算:加法为0,减法为1
- 操作数2为正数记为0,负数记为1
- 运算结果为正数记为0,负数记为1
输出OF
操作数1 | 操作 | 操作数2 | 运算结果 | OF |
---|---|---|---|---|
1 | 0 | 1 | 0 | 1 |
0 | 0 | 0 | 1 | 1 |
… | … | … | … | 0 |
… | … | … | … | 1 |
这样我们就能够根据真值表,得到一个组合逻辑,实现OF了。
当然这只是一个思路而已,举这个例子是为了说明,OF的实现是与十进制运算密切相关的,仅依靠二进制看不出来。
CF与OF分开看
我们前面可以知道,CF有CF的实现逻辑,OF有OF的实现逻辑,实际执行add
运算的时候,我们根据
- 操作数1
- add运算
- 操作数2
- 运算结果
这几个因素,来分别生成OF和CF的结果,二者在机器层级上是相互独立并行工作的两个组合逻辑。
也就是说,CF与OF的组合可能是
- 00
- 01
- 10
- 11
并且二者没有什么关联。
CF、OF与有无符号(整)数运算的关系
注意暂时不谈浮点数!
首先,有无符号是从高级语言层级才能看出来,add
指令进行加法运算,不区分有无符号,不管高级语言是有符号加还是无符号加,都是add
指令,结果完全一样,因此,仅凭借add指令是无法区分的。
那如何区分呢?依靠其他指令以及CF、OF标志位!
通常来说
- CF用于识别无符号数运算的溢出,因为无符号数运算溢出,等价于二进制运算进位了。
- OF用于识别带符号数运算的溢出,这个逻辑的设置,本身就针对带符号数,没什么好说的,补码就针对带符号数
这里再强调人类世界与计算机世界关于整数的转换规则
- 带符号数:补码
- 无符号数:二进制位串
运算与标志位的关系
无含义的纯结果:对于
sub,add
这种不区分有无符号运算的指令,标志位的结果只和运算结果有关,也不需要分开看。根据其他指令识别标志位,给结果赋予含义:但是如果我们去利用标志位做识别,就需要进行分开看,不同的标志位识别,决定了这个运算结果的不同含义,决定了它是带符号数还是无符号数运算,亦或者是比较运算。
x86架构下 CF与OF标志位 带符号和无符号运算 详解相关推荐
- x86架构下的安卓虚拟化
目录 一 国内现状... 1 二 实现方案... 1 三 测试方案... 2 四 技术难点... 4 一 国内现状 国内云手游解决方案大致分为三种: 1.真实手机板卡机器插卡方案 2.使用ARM服务器 ...
- 位运算详解+竞赛常见用法总结
目录 一.位运算详解 二.位运算应用 1.快速幂 2.给定一个数组A, 长度为n,求下面这段程序的值 3.数数字 4.数数字 2 5.nim博弈问题: 6.树状数组 7.判断一个数x是不是2的某次方 ...
- Windows系统下nodejs、npm、express的下载和安装教程详解
这篇文章主要介绍了Windows系统下nodejs.npm.express的下载和安装教程详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下 1. node.js下载 首先进入http://nod ...
- 一篇搞定位运算——java位运算详解
java位运算详解 前言 一.位运算符 &:按位与 |:按位或 ~:按位非 ^:按位异或 <<:左位移运算符 >>:右位移运算符 <<<:无符号右移运 ...
- (转)C语言位运算详解
地址:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html C语言位运算详解 作者:911 说明:本文参考了http://www2.ts ...
- 【C语言位运算的应用】如何按bit位翻转一个无符号整型
其实现思路如下: 将目标数值进行末尾比特位摘取,将所摘取的bit位放到一个相同类型的末尾,目标数值bit位右移,相同类型bit位左移. C语言的位运算符: 实现代码如下: #include & ...
- java 无符号运算_java位运算和无符号运算
计算机在底层使用的是二进制补码进行运算. 计算规则: 正数的原码.反码.补码是其二进制本身. 负数的原码首先计算其二进制数,然后最高位使用1表示负数,反码是最高位不变其它位取反,补码是在反码的基础上进 ...
- php的位运算,php的位运算详解
php的运算符有一类是位运算的,本文主要和大家分享php的位运算详解,希望能帮助到大家. 一:& And按位与 $a&$b 将把二进制$a和二进制$b位数都为1的设为1,其他位为0 例 ...
- linux环境下blastn命令怎么用,Linux环境下通配符及特殊符号使用详解
Linux环境下通配符及特殊符号使用详解 我们现在来介绍通配符的使用,通过通配符的过滤,快速找到想找的文件和目录,比如/etc/目录下有上千个目录和文件,不使用通配符想找一个目录和文件是非常麻烦的和花 ...
最新文章
- 行业B2B网站策划6个基本要求
- 默认的程序化等效项(类型)
- python学习(操作列表、if语句)
- 最新 Docker 部署nginx Tocmat跑项目(解决springBoot启动两次的问题)
- java 查找链表中间元素_如何在Java中一次性查找Java中链表的中间元素
- mysql 长事务查询_MySQL长事务详解
- win7能装mysql_win764位系统怎么安装mysql
- linux 跟踪运行的进程,使用 Linux 的 strace 命令跟踪/调试程序的常用选项
- 那些相见恨晚的 JavaScript 技巧
- Qt UDP Socket丢包问题(实现百兆级速率无丢包)
- C1驾考 科目二 (超详细!文字+实拍图)
- Linux设置终端快捷键
- 超声波清洗机是什么?
- 国产软件很流氓?不,这些国产软件良心且实用,别让它们寒心
- soapui 乱码_接口测试-soapui-中文乱码总结
- 兰州大学计算机科学考研科目,2019兰州大学计算机考研初试科目、参考书目、报录比汇总...
- 突破!龙芯国产域名服务器+红枫2.0 底层技术问题再进一步
- 康耐视visionpro快速入门笔记1
- android智能手机的发展历史,Android智能手机运存发展史
- python之自动发送微信消息
热门文章
- 如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)
- Vue组件间通信:一个例子学会Vue组件-Vue.js学习总结)(转载)
- 使用Maven编译Tomcat源码
- MST:Bad Cowtractors(POJ 2377)
- C# char[]与string之间的相互转换
- GCDAynscSocket简单使用-客户端
- ORACLE连接数据库(备忘)
- 服务器如何返回429状态,Instagram远程服务器返回一个错误:(429)UNKNOWN STATUS CODE...
- Linux usb bus日志如何打开,从linux usb bus节点来认识usb linux usb认识
- c语言中栈堆,C语言中堆和栈的区别