嵌入式系統中研究的移位操作都是無符號的。
ARM是內存與IO統一編址的,ARM中有很多內部外設,SoC中CPU通過向這些內部外設的寄存器寫入一些特定的值來操控這個內部外設,進而操控硬件動作。所以說,讀寫寄存器就是操控硬件。
寄存器的特點是按位進行定義,但是寄存器的讀寫卻是整體32位一起進行的(也就是說你只想修改bit5~bit7是不行的,必須整體32位bit一起寫入)
寄存器操作的要求就是,在設定特定位時不能影響其它位(先讀寄存器,然後再改寄存器,最後寫寄存器)
使用移位獲取特定位爲1的二進制數
(1)譬如需要一個bit3~bit7爲1的二進制數。可以這樣(0x1f<<3)
先計算出bit3~bit7一共有5個bit位, 然後再進行移位運算。
(2)bit3~bit7爲1,bit23~bit25爲1
((0x1f << 3) | (0x7 << 23))
如果需要取特定位爲0(在32位bit位的基礎上,爲0的bit位數小於爲1的bit位數時)
可以在以上基礎上(先運算出相同bit位爲1的數),再結合位取反獲取特定bit位爲0
總結:
(1)如果你要的數比較少爲1,大部分爲0,則可以通過連續的很多1左移n位得到
(2)如果你想要的數是比較少的爲0,大部分位爲1,則可以先構建其位反數,然後再位取反得到
(3)如果你想要的數中連續1(連續0)的部分不止1個,可以通過多段構造,再進行位或即可。
練習:
給定一個整形數a,取出a的bit3~bit8.
第一步:先將這個數bit3~bit8不變,其餘清零
第二部:再將這個數右移3位得到結果。
a = a & (0x3F << 3)
a >> 3
用C語言給一個寄存器的bit7~bit17賦值937(其餘位不受影響)
關鍵點:第一,不能影響其它位;第二:你並不知道原來bit7~bit17中裝的值。
思路: 第一步:先將bit7~bit17全部清零,當然不能影響其它位
第二步:再將937寫入bit7~bit17即可,當然不能影響其它位
a &= ~(0x7ff << 7)
a |= (937 << 7)
用C語言將一個寄存器的bit7~bit17中的值加17(其它位不受影響)
關鍵點:不知道原來的值是多少
第一步:先讀出來原來的bit7~bit17的值
第二步:給這個值加17
第三步:將bit7~bit17清零
第四步:將第三步算出來的值寫入bit7~bit17
tmp = a & (0x3ff << 7)
tmp = tmp >> 7
tmp += 17
a &= ~(0x3ff << 7)
a |= tmp << 7