赞
踩
1.常用位操作符
位与&:
(1)位与符号是一个&,两个&&是逻辑与。
(2)位与就是两个操作数按照二进制数,每一位进行逻辑与。
位或|:
(1)位或是一个|,逻辑或是||。
(2)位与就是两个操作数按照二进制数,每一位进行逻辑或。
位取反:
(1)C语言的位取反~,逻辑取反是!。
(2)按位取反是将操作数的二进制位逐个按位取反(1变成0,0变成1)﹔而逻辑取反是真(在c语言中只要不是0的任何数都是真)变成假(在c语言中只有O表示假)、假变成真。
位异或^:
(1)真值表:1^1 = 0 , 0^0 = 0,1^0=1,0^1=1。
(2)相等为0,不等为1。
位于、位或、位异或的特点:
位于:(任何数,就是就是1或者0)与1位与无变化,与0位与变成0。
位或:(任何数,就是就是1或者0)与1位或变成1,与0位或无变化。
位异或:(任何数,就是就是1或者0)与1位异或会取反,与0位异或无变化。
左移位、右移位
C语言的移位要取决于数据类型。
对于无符号数,左移时右侧补0(相当于逻辑移位)
对于无符号数,右移时左侧补0(相当于逻辑移位)
对于有符号数,左移时右侧补0(叫算数移位,相当于逻辑移位)
对于有符号数,右移时左侧补符号位(叫算数移位,正数补0,负数补1)
嵌入式中研究的移位,以及使用的移位是无符号数。
(1)ARM是内存与IO统一编址的,ARM中有很多内部外设,SoC中CPU通过像这些内部外 设的寄存器写入一些特定的值来操控这个内部外设,进而操控硬件动作。所以可以 说:读写寄存器就是操控硬件。
(2)寄存器的特点是按位进行规划和使用,但读写确实32位一起进行的。
(3)寄存器操作的要求:在设定特定位时不能影响其他位。
(4)读-改-写三部曲。读改写的理念就是,当 想改变寄存器的某些特定位时,不会直接去 写它,而是,先读出原来的值,然后再这个基础上修改特定位,再将修改的值写回寄 存器。效果:在不影响其他位的情况下,修改了自己关心的值。
任何数与1位与不变,与0位与变成0。
如果希望将一个寄存器的某些为变成0,其他的不变,则构造一个二进制数,要清零的
位置为0,不变位置为1,把原来的数与构造的数进行位与。
任何数与1位或变为1,与0位或不变。
如果希望将一个寄存器的某些为变成1,其他的不变,则构造一个二进制数,要置1的
位置为1,不变位置为0,把原来的数与构造的数进行位或。
任何数与1位异或取反,与0位或不变。
如果希望将一个寄存器的某些为取反,其他的不变,则构造一个二进制数,要取反的
位置为1,不变位置为0,把原来的数与构造的数进行位异或。
优势:可以完成工作,难道也不大,操作起来也不是很麻烦。
劣势:依赖工具,不直观。
(1)比如需要bit3~bit7为1,其他位置全为0的二进制数。可以这样(0x1f<<3).
(2)更难一点,获取bit3~bit7为1,bit23~bit25为1,其余位为0:((0x1f<<3) | (7<<23))。
(1)比如需要bit4~bit10为0,其他位置全为1的二进制数。
运用方法2,可以((0xf<<0) | (0x1fffff<<11))。
结合取反,可以~(0x7f<<4)。
4.总结
(1)如果要的数比较少的数为1,大部分为0,则通过连续的1,左移得到。
(2)如果要的数比较少的数为0,大部分为1,则通构建其反数,然后取反。
(3)如果要的数连续1(连续0)的部分不止一个,这可以分别构造,然后位或。
要置1用(|),要清零用&,要取反用^,~和<< >>用来构建特定二进制数。
(1)给定一个整型数a,设置a的bit3,保证其他位不变。
a = a | (1<<3) 或者 a |= (1<<3)
(2)给定一个整型数,设置bie3~bie7,保证其他位置不变。
a = a | (0x1f<<3) 或者a |= (0x1f<<3)
(3)给定一个整数a,清楚a的bit15,保证其他位不变。
a = a & (~(1<<15)) 或者 a &= (~(1<<15))
(4)给定一个整型数a,清楚a的bit15~bit23,保证其他位不变。
a = a & (~(0x1ff<<15)) 或者a &= (~(0x1ff<<15))
(5)给定一个整型数a,取出a的bit3~bit8。
第一步:先将这个数bit3~~bit8不变,其余位全部清零。
第二步:再将其右移3位得到结果。
第三步:C语言实现即可。
a &= (0x3f << 3);
a >>=3;
(6)用C语言给一个寄存器的bit7~bit17赋值937。(不能影响其他位)
第一步,先将bit7~-bit17全部清零,不能影响其他位。
第二部,位或赋值。
a &= ~(0x7ff<<7);
a |= (937 << 7);
(7)用C语言给一个寄存器的bit7~bit17中的值加17(其余位不受影响)。
第一步,先读出原来bit7~~bit17的值
第二步,给这个值加17
第三步,将bit7~~bit17清零
第四步,将加数赋值进去
int temp = a&(0x3ff << 7);
temp >>=7;
temp+=17;
a &= ~(0x3ff<<7);
a |=(temp<<7);
(8)用C语言给一个寄存器的bit7~bit17赋值937,同时给bit21~bit25赋值17。
a &= ~((0x7ff<<7) | (0x1f<<21));
a |= ((937<<7) | (17<<21));
1.直接用宏来置位、复位(最右边为第一位)
U的意思时表示无符号数。
#define SET_NTH_BIT(x , n) (x | ((1U) <<(n-1) )
#deine CLEAR_NTH_BIT(x , n) (x &~((1U)<<(n-1)) )
//~0U得到32个1,然后>>32-(m-n+1)得到前面是32-(m-n+1)个0,后面是m-n+1个1,再<<(n- 1),就得到了从第n位到m位为1,其余位为0。
#define SET_NTH_BIT_m(x , n , m) (x | ((~0U)>>(32-(m-n+1))<<(n-1))
2.截取变量的部分连续位
// ~的优先级高于<< 、>>
//~(~(0U)<<(m-n+1))<<(n-1),~(~(0U)<<(m-n+1))可以给低位m-n+1个1,然后在左移到
n位置。
#define GETBITS(x , n , m ) ( ( x & ~(~(0U)<<(m-n+1))<<(n-1))>> (n-1) )
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。