《嵌入式Linux与物联网软件开发——C语言内核深度解析》一2.4 位运算构建特定二进制数

简介:

本节书摘来自异步社区《嵌入式Linux与物联网软件开发——C语言内核深度解析》一书中的第2章,第2.4节,作者朱有鹏 , 张先凤,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.4 位运算构建特定二进制数

由前面可知,对寄存器特定位进行置1、清零或者取反,关键点在于要事先构建一个特别的数,这个数和原来的值进行位与、位或、位异或操作,即可达到我们对寄存器操作的要求。

自己去算这个数,显然既费时又费脑,虽然依托工具也可以算出来,但缺点就是不直观。如0X0003803A这个数谁能一下报出转换为二进制后为多少?太难了。既然如此,我们完全可以使用位运算(位与、位或、取反等等)快速地构建我们需要的操作数。

2.4.1 使用移位获取特定位为1的二进制数

最简单的就是用移位来获取一个特定位为1的二进制数。如我们需要一个bit3~bit7为1(隐含意思就是其他位全部为0)的二进制数。

我们可以用计算器或者直接用脑子去想。

这个数便是0b11111000 = 0xf8,而这个数并不容易一下就能想出来。

我们来利用二进制构造。

分析bit3~bit7为1,则该数是由5(7-3+1)个二进制的1构成的,只不过是从bit3开始连续排布的,所以我们就想构造一个从bit0开始连续排布的5个二进制1,左移3位即可实现。而这个数很容易就可以想出来,它就是0x1f,现在对这个数左移3位(0x1f << 3 )是不是就实现了呢。

也许,这个对比还不是很明显,我们再来看一个例子:获取bit3~bit7为1,同时bit23~bit25为1,其余位为0的数。

这个时候你用脑子去想是不是开始觉得头大了。

好了,你可以用笔或者计算器算下。这个数是0b0000 0011 1000 0000 0000 0000 1111 1000 = 0x038000f8。

我们来利用二进制构造。

bit3~bit7:以bit0为基准构造结果为0x1f。

bit23~bit25:以bit0为基准构造结果为0x07。

开始移位相或:(0x1f<<3) | (0x07<<23)

对比:假如要用C语言定义该数,如下所示。

int a = 0x038000f8; 
int a = (0x1f<<3) | (0x07<<23);

很显然,第二个可读性和可塑性提高了很多!

2.4.2 结合位取反获取特定位为0的二进制数

这次我们要获取bit4~bit10为0(该数总共32bit),其余位全部为1的数。有了上面的思维之后,想想该怎么做?我想如果你有了上面的思维后,相信聪明的你已经知道解法了吧。

分析:bit4~bit10为0,说明bit31~bit11都为1,bit3~bit0也都为1。
   bit31~bit11:以bit0为基准构造结果为0x1fffff。
   bit3~bit0:以bit0为基准构造结果为0x0f。

所以,结果是(0x1fffff<<11) | (0x0f<<0)。

但是,你有没有发现采用这种方法并没有什么太大的优势。连续为1的位数太多了,这个数字本身就很难构造,所以这种方法的优势损失掉了。这种特定位(比较少)为0而其余位(大部分)为1的数,不适合用很多个连续1左移的方式来构造,而适合左移加位取反的方式来构造。

思路:先试图构造出这个数的反码,再取反得到这个数。例如本例中要构造的数bit4~bit10为0,其余位为1,那我们就先构造一个bit4~bit10为1,其余位为0的数,然后对这个数按位取反即可。

· 构造该数的反码
bit4~bit10为0的数。其反码为bit4~bit10为1,其余bit为0,这个就很容易构造,就是0x7f<<4。

· 对其取反
对其构造的反码进行取反:~(0x7f<<4)。

对比:对该数用C语言定义,效果很明显。

int a = 0x1fffff<<11) | (0x0f<<0);
int a = ~(0x7f<<4);

2.4.3 总结

位与、位或结合特定二进制数,即可完成寄存器位操作需求。

如果你要的这个数中比较少位为1,大部分位为0,则可以通过连续很多个1左移n位得到。

如果你想要的数中比较少位为0,大部分位为1,则可以通过先构建其位反码,然后再位取反来得到。

如果你想要的数中连续1(连续0)的部分不止一个,那么可以通过多段分别构造,然后再彼此位或即可。这时候因为参与位或运算的各个数为1的位是不重复的,所以这时候的位或其实相当于几个数的叠加。

相关实践学习
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
11月前
|
安全 网络协议 Linux
深入理解Linux内核模块:加载机制、参数传递与实战开发
本文深入解析了Linux内核模块的加载机制、参数传递方式及实战开发技巧。内容涵盖模块基础概念、加载与卸载流程、生命周期管理、参数配置方法,并通过“Hello World”模块和字符设备驱动实例,带领读者逐步掌握模块开发技能。同时,介绍了调试手段、常见问题排查、开发规范及高级特性,如内核线程、模块间通信与性能优化策略。适合希望深入理解Linux内核机制、提升系统编程能力的技术人员阅读与实践。
948 1
|
11月前
|
Ubuntu Linux
Ubuntu 23.04 用上 Linux 6.2 内核,预计下放到 22.04 LTS 版本
Linux 6.2 带来了多项内容更新,修复了 AMD 锐龙处理器设备在启用 fTPM 后的运行卡顿问题,还增强了文件系统。
|
11月前
|
Ubuntu Linux
Ubuntu 23.10 现在由Linux内核6.3提供支持
如果你想在你的个人电脑上测试一下Ubuntu 23.10的最新开发快照,你可以从官方下载服务器下载最新的每日构建ISO。然而,请记住,这是一个预发布版本,所以不要在生产机器上使用或安装它。
|
11月前
|
传感器 监控 Ubuntu
10 月发布,Ubuntu 23.10 已升级到 Linux Kernel 6.3 内核
硬件方面,Linux 6.3 引入了在 HID 中引入了原生的 Steam Deck 控制器接口,允许罗技 G923 Xbox 版赛车方向盘在 Linux 上运行;改善 8BitDo Pro 2 有线控制器的行为;并为一系列华硕 Ryzen 主板添加传感器监控。
|
11月前
|
Ubuntu Linux
Ubuntu24.04LTS默认采用Linux 6.8内核,实验性版本可通过PPA获得
IT之家提醒,当下的 Ubuntu 23.10 也是一个“短期支持版本”,该版本将在今年 7 月终止支持,而今年 4 月推出的 Ubuntu 24.04 LTS 长期支持版本将获得 5 年的更新支持。
|
11月前
|
监控 Ubuntu Linux
什么Linux,Linux内核及Linux操作系统
上面只是简单的介绍了一下Linux操作系统的几个核心组件,其实Linux的整体架构要复杂的多。单纯从Linux内核的角度,它要管理CPU、内存、网卡、硬盘和输入输出等设备,因此内核本身分为进程调度,内存管理,虚拟文件系统,网络接口等4个核心子系统。
1070 0
|
11月前
|
Web App开发 缓存 Rust
|
11月前
|
Ubuntu 安全 Linux
Ubuntu 发行版更新 Linux 内核,修复 17 个安全漏洞
本地攻击者可以利用上述漏洞,攻击 Ubuntu 22.10、Ubuntu 22.04、Ubuntu 20.04 LTS 发行版,导致拒绝服务(系统崩溃)或执行任意代码。
|
11月前
|
Ubuntu 机器人 物联网
Linux Ubuntu 22.04 LTS 测试版实时内核已可申请
请注意,在启用实时内核后您需要手动配置 grub 以恢复到原始内核。更多内容请参考:

热门文章

最新文章

相关产品

  • 物联网平台