ir指令、立即数的作用_立即数的判断方法一
在ARM匯編的數(shù)據(jù)處理指令中經(jīng)常會使用到常數(shù),而ARM匯編中規(guī)定使用的常數(shù)必
須是立即數(shù)。ARM立即數(shù)的是由一個8位的常數(shù)循環(huán)右移偶數(shù)位得到的,其中循環(huán)右移
的位數(shù)由一個4位2進(jìn)制的兩倍表示,公式如下:
immediate=immed_8&
簡單的說一個常數(shù)如果可以由一個8位的常數(shù)循環(huán)移位偶數(shù)位得到,那么就是立即數(shù)。
為什么會有立即數(shù)這樣的規(guī)定呢,這是由于所有的ARM指令是精簡指令集,指令長度固定都是32位,對于ARM數(shù)據(jù)處理指令自然也是一樣。數(shù)據(jù)處理指令大致可包含3類,數(shù)據(jù)傳送指令、數(shù)據(jù)算術(shù)邏輯運算指令和數(shù)據(jù)比較指令。在一條ARM數(shù)據(jù)處理指令中,除了要包含處理的數(shù)據(jù)值外,還要標(biāo)識ARM命令名稱,控制位,寄存器等其他信息。這樣在一條ARM數(shù)據(jù)處理指令中,能用于表示要處理的數(shù)據(jù)值的位數(shù)只能小于32位。
ARM在指令格式中設(shè)定,只能用指令機(jī)器碼32位中的低12位來表示要操作的常數(shù)。ARM處理器是按32位來處理數(shù)據(jù)的,ARM處理器處理的數(shù)據(jù)是32位,如果簡單的用這12位來表示,顯然范圍太小了,為了擴(kuò)展到32位,因此使用了構(gòu)造的方法,在12位中用8位表示基本數(shù)據(jù)值,用4位表示位移值,通過用8位基本數(shù)據(jù)值往右循環(huán)移動4位位移值*2次,來表示要操作的常數(shù)。這里要強(qiáng)調(diào)終的循環(huán)次數(shù)是4位位移值乘以2得到的,所以得到的終循環(huán)次數(shù)肯定是一個偶數(shù),為什么要乘以2呢,實質(zhì)還是因為范圍不夠,4位表示位移次數(shù),大才15次,加上8位數(shù)據(jù)還是不夠32位,這樣只能通過ALU的內(nèi)部結(jié)構(gòu)設(shè)計將4位位移次數(shù)乘以2,這樣就能用12位表示32位常數(shù)了。
通過循環(huán)偶數(shù)位得的到操作數(shù),擴(kuò)大了操作數(shù)的范圍,但也帶來了問題,并不是每個數(shù)據(jù)都能通過8位基本數(shù)據(jù)循環(huán)移動偶數(shù)為得到,如果你在ARM數(shù)據(jù)處理指令中使用的操作數(shù),不是立即數(shù),比如MOV R1,#0x12345678,編譯器就會報錯,所以我們在使用前必須進(jìn)行判斷,這也是很多ARM相關(guān)求職筆試中常考的一道題目。
那怎樣怎么快速判斷一個數(shù)是否是立即數(shù),對于簡單的數(shù)字我們可以直接判斷,比如小于255的數(shù)字肯定是立即數(shù)。對相對復(fù)雜的數(shù)字進(jìn)行判斷就需要先把它轉(zhuǎn)換為2進(jìn)制形式,然后根據(jù)定義進(jìn)行判斷了。我這里總結(jié)了個比較快速的方法:
1、把數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制形式,從低位到高位寫成4位1組的形式,高位一組不夠四位的,在高位前面補(bǔ)0。
2、數(shù)1的個數(shù),如果大于8個肯定不是立即數(shù),如果小于等于8進(jìn)行下面步驟。
3、如果數(shù)據(jù)中間有連續(xù)的大于等于24個0,循環(huán)左移4的倍數(shù),使高位全為0。
4、找到高位的1,去掉前面大偶數(shù)個0。
5、找到低位的1,去掉后面大偶數(shù)個0。
6、數(shù)剩下的位數(shù),如果小于等于8位,那么這個數(shù)就是立即數(shù),反之就不是立即數(shù)。
針對可能現(xiàn)的情況,我舉5個典型例子:
(1)0x4FF (2)0x122 (3)0x234 (4)0xF000000F (5)0x8000007F
例1: 0x4FF
第一步:0100 1111 1111
第二步:其中1的個數(shù)是9個,大于8個,判定不是立即數(shù)
例2: 0x122
第一步: 0001 0010 0010
第二步: 其中1的個數(shù)4個,小于8,繼續(xù)
第三步: 其中沒有連續(xù)大于等于24個0,繼續(xù)
第四部: xx01 0010 0010 (高位前面有3個0,大偶數(shù)2,去掉2個0)
第五步: xx10 0011 0010 (低位后面只有1個0,大偶數(shù)0)
第六部: 剩下10 0011 0010 共10位,大于8,判定0x122不是立即數(shù)
例3: 0x234
第一步: 0010 0011 0100
第二步: 其中1的個數(shù)4個,小于8,繼續(xù)
第三步: 其中沒有連續(xù)大于等于24個0,繼續(xù)
第四部: xx10 0011 0100
第五步: xx10 0011 01xx
第六部: 剩下10 0011 01 共8位,等于8,判定0x234是立即數(shù)
例4: 0xF000000F
第一步: 1111 0000 0000 0000 0000 0000 0000 1111
第二步: 其中1的個數(shù)8個,沒有大于8,繼續(xù)
第三步: 其中有連續(xù)24個0,循環(huán)左移4位,使高位全為0
0000 0000 0000 0000 0000 0000 0000 1111 1111
第四部: xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 1111
第五步: xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 1111
第六部: 剩下1111 1111共8位,等于8,判定0xF000000F是立即數(shù)
例5: 0x8000007F
第一步: 1000 0000 0000 0000 0000 0000 0111 1111
第二步: 其中1的個數(shù)8個,沒有大于8,繼續(xù)
第三步: 其中有連續(xù)24個0,循環(huán)左移4位,使高位全為0
0000 0000 0000 0000 0000 0000 0111 1111 1000
第四部: xxxx xxxx xxxx xxxx xxxx xxxx 0111 1111 10xx
第五步: xxxx xxxx xxxx xxxx xxxx xxxx 0111 1111 10xx
第六部: 剩下0111 1111 10共10位,等于8,判定0x7000008F是立即數(shù)
問題還沒有結(jié)束,我們在ARM匯編中如何規(guī)避立即數(shù)這個問題呢,其實可以使用ARM匯編LDR偽指令,例如直接把MOV指令變?yōu)?#xff0c; LDR R1,=0x12345678這樣編譯器就不會報錯了。但這種方法也有弊端會增加開銷和影響執(zhí)行效率。同時ARM匯編中還有有效數(shù)的概念,比如 MOV R1,#0xFFFFFFFF 指令中 0xFFFFFFFF 不是立即數(shù),但是是有效數(shù),編譯器自動把原指令變換為 MVN R1,#0,也不會報錯。有效數(shù)判定:原數(shù)是立即數(shù)或者原數(shù)反碼是立即數(shù)。
總結(jié)
以上是生活随笔為你收集整理的ir指令、立即数的作用_立即数的判断方法一的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本月十六日外地车开,今天停吗?
- 下一篇: 32 vs 开发wince_“激光大炮”