位运算与寄存器之间的关系

一、寄存器操作

SOC片内外设由若干个寄存器控制,IO 操作的寄存器与内存统一编址,如果我们要操作片内外设,那么就是操作片内外设的控制寄存器。因此,控制硬件就是读写寄存器(寄存器亦可理解为特定地址的内存)。

SOC中一个寄存器的数据宽度一般是32位,每个位可以配置为0或者1,单个bit 或相邻几个bit 一起控制片上外设某个属性的状态。单个 bit 最多控制两种状态,三个 bit 最多控制8种状态。因此寄存器的特定bit配置为0或1,即可以实现对硬件的控制。

二、寄存器特定位清零(&)

假设我们希望将一个寄存器的某些特定位变成0,并且不会影响其他位的改变,我们可以构造一个合适的1和0组成的数,和原本的这个寄存器进行与运算,就可以将特定的位进行清零操作。

案例实战

例子:现在有个寄存器R = 0XAAAAAAAA ,希望将8~23位进行清零操作并且其他位保持不变

我们可以使用按位与来实现

R &= 0xFF0000FF; 

 运行结果为:

经过以上读、改、写操作之后,R的值为0xAA0000AA,达到了特定位清零的目的

三、寄存器特定位置1(|)

现在我们已经知道可以使用按位与(&)可以对特定寄存器进行清零操作,那么我们是否可以根据按位或的规则来对寄存的特定为进行置1操作呢?答案是可以

案例实战

例子:现在有个寄存器R = 0XAAAA00AA ,希望将8~23位进行置1操作并且其他位保持不变

具体实现程序:

	int R = 0XAAAA00AA;
	R |= 0X00FFFF00;
	printf("R = 0X%02X\n", R);

实现结果:

经过以上读、改、写操作之后,R的值为0XAAFFFFAA,达到了特定位置1的目的

四、寄存器特定位取反(~)

我们前面了解了如何对特定为进行清零或者置1操作,那么我们如何实现寄存器特定为进行取反操作呢?什么是特定位取反呢?就是使特定位上的0变成1、1变成0.经过一轮分析发现使用位异或可以实现(^)

案例实战

例子:现在有个寄存器R = 0XAAAA55AA ,希望将8~23位进行取反操作并且其他位保持不变

具体实现程序:

	int R = 0XAAAA55AA;
	R ^= 0X00FFFF00;   //进行位异或运算
	printf("R = 0X%02X\n", R);

实现结果:

经过以上读、改、写操作之后,R的值为0XAA55AAAA,达到了特定位置取反目的

五、构建特定的二进制数

由前面可知,对寄存器特定位进行置1、清零或者取反,关键点在于要事先构建一个特别的数,这个数和原来的值进行位与、位或、位异或操作,即可达到我们对寄存器操作的要求。自己去算这个数,显然既费时又费脑,虽然依托工具也可以算出来,但缺点就是不直观。如0X0003803A这个数谁能一下报出转换为二进制后为多少?这个也太难了。那么应该怎么办呢?既然如此,我们完全可以使用位运算(位与、位或、取反等等)快速地构建我们需要的操作数。

5.1 移位获取特定位为1的二进制

简单的说就是通过移位的方式来获取一个特定位为1的二进制数。

案例实战

假设我们现在需要将寄存器的bit3~bit7置1,那么我们应该如何来做

首先动一动我们的小脑筋,想了一下

0b11111000 = 0xf8,然而这个数并不能一下想出来吧,那么我们有没有简单点的方法

首先咱们分析下:

bit3~bit7:以bit0为基础构造结果为0X1f

然后开始移位即可 R = (0x1f<<3)

	int R = 0;
	R = (0x1f << 3);   
	printf("R = 0X%02X\n", R);

运行结果为:

这个例子可能还不太明显的感受到

接下来咱们看另一个例子:此时我们需要将bit3~bit7置1,同事将bit23~25置1

这个时候如果采用转换二进制的方法估计会比较头大,咱们借助计算机算下,这个二进制数是多少

通过计算器计算得到R = 0X0308000f8

那么咱们有没有简便一点的方法呢?答案是当然有

第一步咱们来构造二进制

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

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

开始进行移位操作:R = (0x1f<<3)| (0x07<<23)

代码如下:

	int R = 0;
	R = (0x1f << 3) | (0x07 << 23);   
	printf("R = 0X%02X\n", R);

结果如下:

这样计算起来就是相当的方便

5.2 结合位取反获取特定位为0

直接举例说明,原理与之气那类似

我们想要获取bit4~bit10为0,其他数全部为1。

首先咱们来分析下这个需求

bit4~bit10为0,说明bit31~bit11及bit0~bit3为1

那么构造bit0~bit3为:0x0f

构造bit11~bit31为:0x1fffff

直接进行移位梳理即可

R = (0x0f << 0)|  (0x1fffff << 11)即可结果如下

通过计算器来看下0Xfffff80f这个数的4~10位是否为0;

通过计算器发现,确实可以实现特定位清零的作用

构造反码

bit4~bit10为0的数,其反码为bit4~bit10为1,其余bit为0,

其实现为:R = ~(0x7F<<4)

实现如下

六、总结

以上就是位运算在寄存器中的使用,有什么不足的地方还请大家评论补充!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓬莱菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值