對ARM數據處理指令中#immed_8r的理解
見(jiàn)書(shū)中有如下描述“大多數ARM通用數據處理指令有一個(gè)靈活的第二操作數(flexible second operand)。”其中的#immed_8r的第二操作數形式讓我百思不得其解。查到ZLG的課件(感謝)有如下圖表:

#immed_8r這個(gè)立即數的要求是滿(mǎn)足如上8位位圖,即兩點(diǎn)要求:
1·能用長(cháng)度為8位的框框將這個(gè)數框起來(lái)。
錯誤示范:先假設#immed_8r值為0x101(00000000 00000000 00000001 00000001)紅色加粗部分為9位,無(wú)法滿(mǎn)足此要求,編譯會(huì )出錯。
2·這個(gè)數必須能由一個(gè)8位的常數循環(huán)右移偶數次得到。
錯誤示范:設#immed_8r值為0x102(00000000 00000000 00000001 00000010)假如把紅色加粗部分看做8位常數框(滿(mǎn)足要求1)??梢钥闯?,這是經(jīng)過(guò)奇數次循環(huán)右移得到的結果,不滿(mǎn)足要求2。
0x102(00000000 00000000 00000001 00000010)假如試圖滿(mǎn)足要求2,以紅色加粗部分看做是由原常數循環(huán)右移0次(0、2、4、……、30都是偶數次,后面將解釋?zhuān)┑玫?,則會(huì )不滿(mǎn)足要求1(9位)。所以編譯也會(huì )報錯。
上面的要求使得#immed_8r不能直接取遍32位所有數(是不是ARM的所有立即數都有這個(gè)要求嗎?對寄存器的立即數操作呢?后來(lái)(11.11.16)學(xué)習到:偽指令LDR{cond} register,=[expr | label-expr]貌似能夠存入任意32位數,但是具體限制又是什么呢?),為什么不能一步到位,下面根據參考的博文來(lái)分析:
ARM的數據處理指令語(yǔ)法通常為(以AND、ORR、EOR、BIC為例):op {cond}{S} Rd,Rn{,Operand2}
但其實(shí)它的ARM的指令編碼如下:

其中[7:0]位就是要求8位的原因,留給立即數數值的位數只有8位。
而[11:8]位rotate是循環(huán)(右移)次數,是4位的。
我設想可能設計者是這樣考慮的:就算12個(gè)位全部用來(lái)存立即數,也只能表示2^12次個(gè)數,和2^32次個(gè)數相差很遠。于是使用循環(huán)(右移)次數標記來(lái)與8位立即數組合。
但假如每+1,只右移1位的話(huà),全部加滿(mǎn)也才右移了2^4=16位(0~15)。所以設定每+1標記,循環(huán)右移2位,這樣就能移遍32位(0~15 X 2)。
即便是這樣,也不能表示完2^32個(gè)值,就如同上面的錯誤示范的數是不符合要求的。這就有了bootload中這樣的語(yǔ)句(我復制的是6410的,書(shū)是ARM7的,看來(lái)學(xué)這點(diǎn)一直沒(méi)變):
組合起來(lái),才能表示#0xffff(指令還沒(méi)學(xué)完……只能說(shuō)到這里)
ARM門(mén)檻高,知識點(diǎn)多而且細……大家繼續努力吧~!
評論