《嵌入式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的位是不重復的,所以這時候的位或其實相當于幾個數的疊加。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的《嵌入式Linux与物联网软件开发——C语言内核深度解析》一2.4 位运算构建特定二进制数...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《D3.js数据可视化实战手册》—— 1
- 下一篇: 在 Linux 上使用 Meld 比较文