《嵌入式Linux与物联网软件开发——C语言内核深度解析》一2.4 位运算构建特定二进制数...
本節(jié)書摘來自異步社區(qū)《嵌入式Linux與物聯(lián)網(wǎng)軟件開發(fā)——C語言內(nèi)核深度解析》一書中的第2章,第2.4節(jié),作者朱有鵬 , 張先鳳,更多章節(jié)內(nèi)容可以訪問云棲社區(qū)“異步社區(qū)”公眾號查看。
2.4 位運算構(gòu)建特定二進(jìn)制數(shù)
由前面可知,對寄存器特定位進(jìn)行置1、清零或者取反,關(guān)鍵點在于要事先構(gòu)建一個特別的數(shù),這個數(shù)和原來的值進(jìn)行位與、位或、位異或操作,即可達(dá)到我們對寄存器操作的要求。
自己去算這個數(shù),顯然既費時又費腦,雖然依托工具也可以算出來,但缺點就是不直觀。如0X0003803A這個數(shù)誰能一下報出轉(zhuǎn)換為二進(jìn)制后為多少?太難了。既然如此,我們完全可以使用位運算(位與、位或、取反等等)快速地構(gòu)建我們需要的操作數(shù)。
2.4.1 使用移位獲取特定位為1的二進(jìn)制數(shù)
最簡單的就是用移位來獲取一個特定位為1的二進(jìn)制數(shù)。如我們需要一個bit3~bit7為1(隱含意思就是其他位全部為0)的二進(jìn)制數(shù)。
我們可以用計算器或者直接用腦子去想。
這個數(shù)便是0b11111000 = 0xf8,而這個數(shù)并不容易一下就能想出來。
我們來利用二進(jìn)制構(gòu)造。
分析bit3~bit7為1,則該數(shù)是由5(7-3+1)個二進(jìn)制的1構(gòu)成的,只不過是從bit3開始連續(xù)排布的,所以我們就想構(gòu)造一個從bit0開始連續(xù)排布的5個二進(jìn)制1,左移3位即可實現(xiàn)。而這個數(shù)很容易就可以想出來,它就是0x1f,現(xiàn)在對這個數(shù)左移3位(0x1f << 3 )是不是就實現(xiàn)了呢。
也許,這個對比還不是很明顯,我們再來看一個例子:獲取bit3~bit7為1,同時bit23~bit25為1,其余位為0的數(shù)。
這個時候你用腦子去想是不是開始覺得頭大了。
好了,你可以用筆或者計算器算下。這個數(shù)是0b0000 0011 1000 0000 0000 0000 1111 1000 = 0x038000f8。
我們來利用二進(jìn)制構(gòu)造。
bit3~bit7:以bit0為基準(zhǔn)構(gòu)造結(jié)果為0x1f。
bit23~bit25:以bit0為基準(zhǔn)構(gòu)造結(jié)果為0x07。
開始移位相或:(0x1f<<3) | (0x07<<23)
對比:假如要用C語言定義該數(shù),如下所示。
int a = 0x038000f8; int a = (0x1f<<3) | (0x07<<23);很顯然,第二個可讀性和可塑性提高了很多!
2.4.2 結(jié)合位取反獲取特定位為0的二進(jìn)制數(shù)
這次我們要獲取bit4~bit10為0(該數(shù)總共32bit),其余位全部為1的數(shù)。有了上面的思維之后,想想該怎么做?我想如果你有了上面的思維后,相信聰明的你已經(jīng)知道解法了吧。
分析:bit4~bit10為0,說明bit31~bit11都為1,bit3~bit0也都為1。
bit31~bit11:以bit0為基準(zhǔn)構(gòu)造結(jié)果為0x1fffff。
bit3~bit0:以bit0為基準(zhǔn)構(gòu)造結(jié)果為0x0f。
所以,結(jié)果是(0x1fffff<<11) | (0x0f<<0)。
但是,你有沒有發(fā)現(xiàn)采用這種方法并沒有什么太大的優(yōu)勢。連續(xù)為1的位數(shù)太多了,這個數(shù)字本身就很難構(gòu)造,所以這種方法的優(yōu)勢損失掉了。這種特定位(比較少)為0而其余位(大部分)為1的數(shù),不適合用很多個連續(xù)1左移的方式來構(gòu)造,而適合左移加位取反的方式來構(gòu)造。
思路:先試圖構(gòu)造出這個數(shù)的反碼,再取反得到這個數(shù)。例如本例中要構(gòu)造的數(shù)bit4~bit10為0,其余位為1,那我們就先構(gòu)造一個bit4~bit10為1,其余位為0的數(shù),然后對這個數(shù)按位取反即可。
· 構(gòu)造該數(shù)的反碼
bit4~bit10為0的數(shù)。其反碼為bit4~bit10為1,其余bit為0,這個就很容易構(gòu)造,就是0x7f<<4。
· 對其取反
對其構(gòu)造的反碼進(jìn)行取反:~(0x7f<<4)。
對比:對該數(shù)用C語言定義,效果很明顯。
int a = 0x1fffff<<11) | (0x0f<<0); int a = ~(0x7f<<4);2.4.3 總結(jié)
位與、位或結(jié)合特定二進(jìn)制數(shù),即可完成寄存器位操作需求。
如果你要的這個數(shù)中比較少位為1,大部分位為0,則可以通過連續(xù)很多個1左移n位得到。
如果你想要的數(shù)中比較少位為0,大部分位為1,則可以通過先構(gòu)建其位反碼,然后再位取反來得到。
如果你想要的數(shù)中連續(xù)1(連續(xù)0)的部分不止一個,那么可以通過多段分別構(gòu)造,然后再彼此位或即可。這時候因為參與位或運算的各個數(shù)為1的位是不重復(fù)的,所以這時候的位或其實相當(dāng)于幾個數(shù)的疊加。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的《嵌入式Linux与物联网软件开发——C语言内核深度解析》一2.4 位运算构建特定二进制数...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《D3.js数据可视化实战手册》—— 1
- 下一篇: linux 其他常用命令