位操作小结与宏定义

讲道理,在没接触arm裸机前一直觉得位运算挺鸡肋的,就算是当年的汇编课设也没怎么用位操作。但是在统一编址的arm平台,操作外设主要靠操作寄存器,这时候位操作真的是必不可少,当然位操作和位运算是分不开的。


(1).位运算: 位与&,位或 | ,位取反~,位异或^(奇数个1异或结果为1,其他为0).

            算数运算(逻辑运算):算数与&&,算数或  | | ,算数取反!。(逻辑里无符号要么0,要么都是1)

    位移操作:左移<<,右移>>。


(2).常说的置位指的是置1,清除指的是置0。

           特定位置1:位或一个特定位为1,其他位为0的数即可。-------------------------------------------->a  |=(b<

           特定位置0:位与一个特定位为0,其他为为1的数即可。(常用取反获得) ---------------------->a &=~(b<

           取出特定位:位与一个特定位为1,其他位为0 的数即可。------------------------------------------> d = a &  (b<

有没有发现上面的数互为取反,对的!要构造这样的多用取反和移位操作。


具体实例:   

a 为一寄存器值。

//现在我要让他bit 4 ~bit 7置为0;bit 8~bit 11写入965;再取出bit 8 ~ bit 11.

a & =~(0xf<<4)        (从多少bit开始就移多少位)

a | =~(0xf<<8)  ; a | =(965<<8)

int b= (a & ( 0xf<<8) >>8)



    (3).如何构造任意位的1;例如bit n到 bit m位为1。

 a =  ~(~(0U)<<(m-n+1));                                                                         //U代表无符号数,~(0U)表示0xFFFF

或者

a = ~(0U)>>(32-(m-n+1));                                                                  


    (4).与宏定义结合的位操作解析。注意宏定义的外面一定要加上括号。

// 将x的第n位置位                                                                                    //这里的第n位实际上是bit (n-1) ,下同         

         #define SET_NTH_BIT(x, n)               (x | ((1U)<<(n-1)))


//将x的第n位清除

#define CLEAR_NTH_BIT(x, n)           (x & ~((1U)<<(n-1)))


//截取x的第n到第m位

#define GETBITS(x, n, m)                      ((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1)) 


分析第三个:~(~(0U)<<(m-n+1))                                            //获得m-n+1位的1 ,~优先级大于<<

                       x &       ~(~(0U)<<(m-n+1))     <<(n-1)              // 获得n到m位          ,<<优先级大于&

       (x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1)        //将获得到的数右移n-1位,即得到截取部分。


注意:~(0U)表示0xFFFF

优先级:~             >                  移位(<<,>>)               >   按位操作(&>|) 


位操作小结与宏定义_第1张图片

你可能感兴趣的:(C语言若干问题)