ARM处理器中“8位位图”
?????? 首先從ARM指令系統的語法格式說起。
?????? 一條ARM指令語法格式分為如下幾個部分:
?????? <opcode>{<cond>}{S} <Rd>,<Rn>{,<shifter_operand>}
????? 其中,<>內的項是必須的,{}內的項是可選的,如<opcode>是指令助記符,是必須的,而{<cond>}為指令執行條件,是可選的,如果不寫則使用默認條件AL(無條件執行)。
????????????? Opcode?? 指令助記符,如LDR,STR 等
????????????? Cond?????? 執行條件,如EQ,NE 等
????????????? S?????????? 是否影響CPSR 寄存器的值,書寫時影響CPSR,否則不影響
?????????????Rd????????? 目標寄存器
???????????? Rn????????? 第一個操作數的寄存器
???????????? shifter_operand?????? 第二個操作數
?
其指令編碼格式如下:
當第2 個操作數的形式為:#immed_8r常數表達式時“該常數必須對應8位位圖,即常數是由一個8位的常數循環移位偶數位得到的?!逼湟馑际沁@樣:#immed_8r在芯片處理時表示一個32位數,但是它存儲的時候是由一個8位數(比如:01011010,即0x5A)通過循環移位偶數位得到(1000 0000 0000 0000 0000 0000 0001 0110,就是0x5A通過循環右移2位(偶數位)的到的)。
????? 但是一個1010 0000 0000 0000 0000 0000 0001 0110,就不符合這樣的規定,編譯時一定出錯。因為你可能通過將1011 0101循環右移3位得到它,但是不可能通過循環移位偶數位得到。另一個1011 0000 0000 0000 0000 0000 0001 0110,也不符合這樣的規定,按移位算是由1 0110 1011循環右移4位得到它,但是很明顯:1 0110 1011 有9位,不符合。
???? 為什么要有這樣的規定?
???? 有位大哥的理解是:
???? 要從指令編碼格式來解釋(這就是我為什么一開始講的是指令編碼格式),仔細看表格中的shifter_operand所占的位數:12位。要用一個12位的編碼來表示任意的32位數是絕對不可能的(12位數有2^12種可能,而32位數有2^32種)。但是又要用12位的編碼來表示32位數,怎么辦? ???
??? 只有在表示數的數量上做限制。通過編碼來實現用12位的編碼來表示32位數。
??? 在12位的shifter_operand中:8位存數據,4位存移位的次數。8位存數據:解釋了“該常數必須對應8位位圖”。
??? 4位存移位的次數:解釋了為什么只能移偶數位。4位只有16種可能值,而32位數可以循環移位32次(32種可能),那就只好限制:只能移偶數位(兩位兩位地移,好像一個16位數在移位,16種移位可能)。這樣就解決了能表示的情況是實際情況一半的矛盾。
???? 所以對#immed_8r常數表達式的限制是解決指令編碼的第二個操作數位數不足以表示32位操作數的無奈之舉,但在我看來:這個可以說是聰明的做法。因為如果直接用12位數來表示32位操作數,只能表示0 到(2^12-1)。大于(2^12-1)的數就沒辦法表示了。而且細細想來“8位存數據,4位存移位的次數”,應該是最好的組合了(我并未想過所有的組合,只是順便試了幾個)。所以被循環移位偶數位(0,2,4,...28,30),并且只能向右循環。
------------------------------------------------------------------------------------------------------------------------?
? 有了上述解釋,接下來舉例說明就很清楚了:
?
? 指令①:?? AND?R1,R2,#0xff
??當處理器處理這條指令的第二操作數0xff時,因為0xff為8位二進制數,所以處理器就將其直接放進8位“基本”數中,而4位“移位”數則為0.
??指令②: ? AND?R1,R2,#0x104
??當處理器處理這條指令的第二操作數0x104時,因為此時0x104已經超過了8位二進制數,所以處理器就要將其“改造”一下,我們先把0x104轉換成二進制0000 0000 0000 0000 0000 0001 0000 0100,我們可以看到,這個數是0000 0000 0000 0000 0000 0000 0100 0001通過循環右移30位得到的,因此改造后的結果是8位“基本”數中存放0100 0001,而“移位”數為15。
??指令③:? ?AND?R1,R2,#0xff000000
??當處理器處理這條指令的第二操作數0xff000000時,處理器同樣要對其“改造”,我們先把0xff000000轉換成二進制1111 1111 0000 0000 0000 0000 0000 0000,我們可以看到,這個數是0000 0000 0000 0000 0000 0000 1111 1111通過循環右移8位得到的,因此改造后的結果是8位“基本”數中存放1111 1111,而“移位”數為4。
?
?我想,通過以上的三個例子,就應該明白了8位位圖的原理了。但是,有些數并不符合8位位圖的原理,這樣的數在進行程序編譯時,系統將會提示出錯? 。
?
下面再舉幾個違反8位位圖的例子:
比如0x101,轉換成二進制后位0000 0000 0000 0000 0000 0001 0000 0001,像這個數,無論向右循環幾位,都無法將兩個1同時放到低8位中,因此不符合8位位圖;再比如0x102,轉換成二進制后位0000 0000 0000 0000 0000 0001 0000 0010,如果將兩個1同時放到低8位中,即轉換成二進制后為0000 0000 0000 0000 0000 0000 1000 0001,需要將此二進制數向右移31位,這也不符合循環右移偶數位的條件,因此0x012也不符合8位位圖;再舉一個0xff1,轉換成二進制后將會有9個1,不可能將其同時放入8位中,因此當然也不符合啦。
???通過正反例的比較,可以總結如下:第一,判斷一個數是否符合8位位圖的原則,首先看這個數轉換成二進制后1的個數是否不超過8個,如果不超過8個,再看這n個1(n<=8)是否能同時放到8個二進制位中,如果可以放進去,再看這八個二進制位是否可以循環右移偶數位得到起初被判斷的那個數值,如果可以,則此數值即為符合8位位圖原理,否則,不符合。第二,用12位的編碼來表示一個任意的32位數是不可能的,只能通過循環右移八位二進制數偶數位來得到一部分32位數,其余的無法表示的32位數,只有通過其它途徑獲得了,比如0xffffff00,可以通過0x000000ff按位取反得到,因此在以后的編程中,一定要注意用到的第二操作數是否符合8位位圖。
?
總結
以上是生活随笔為你收集整理的ARM处理器中“8位位图”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于const变量的一点理解
- 下一篇: ARM处理器寄存器