ARM匯編中的立即數(shù)
在eVC編譯出的匯編代碼中我看到這樣的語句:
mov r2, #0xFF, 28 和 orr r2, r2, #0xB
這樣得到的結(jié)果時 r2=#0xffb ,
他試圖更直接一點優(yōu)化成一句:MOV r2,#0xffb
但是這樣之后編譯就出了問題:error A0092: no immediate rotate operand can be created: 4091
------------------------------------我是無辜的分割線--------------------------------
本文引用地址:http://m.butianyuan.cn/article/201611/317884.htm在 mov r2,#0xffb 這句中,不是MOV的用法出錯,而是立即數(shù)用法出錯。
立即數(shù)的用法定義在Arm Architechture Reference Manual(簡稱ARMARM)的A5-4頁開始
很重要的一段:
An immdediate operand value is formed by rotating an 8-bit constant (in a 32-bit word) by an even number of bits (0,2,4,8,26,28,30). Therefore, each instruction contains an 8-bit constant and a 4-bit rotate to be applied to that constant.
Some valid constants are:
0xFF, 0x104, 0xFF0, 0xFF00, 0xFF000, 0xFF000000, 0xF000000F
Some invalid constants are:
0x101, 0x102, 0xFF1, 0xFF04, 0xFF003, 0xFFFFFFFF, 0xF000001F
而在下面的A5-6頁中提到
shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
以及
Some values of
所以,綜上所述,首先解釋清楚了 mov r2,#0xFF,28 一句。28并不是第三個操作數(shù),而是和0xFF并在一起作為立即數(shù)使用,將0xFF循環(huán)右移28位。而這里必須強(qiáng)調(diào)右移XX位必須是個偶數(shù),因為它將等于 rotate_imm*2,那么在該指令的機(jī)器碼中rotate_imm = 14, 也就是在32-BIT的機(jī)器碼中第11到第8 bit = 1110B
然后再來看 mov r2,#0xFFB 的出錯情況
0xFFB = 111111111011B,很顯然按照 shifter_operand = immed_8 Rotate_Right (rotate_imm * 2) 的公式, shifter_operand = 0xFFB時無法得到有效的 immed_8 和 rotate_imm, 所以編譯出現(xiàn)錯誤 error A0092: no immediate rotate operand can be created: 4091 也可以理解了,它應(yīng)該是說無法生成rotate_imm,實際上immed_8也是無法生成的。
關(guān)于立即數(shù)如何分解成immed_8和rotate_imm,可以參考上面給出的valid constants和invalid constants,簡而言之,如果該立即數(shù)可以分解成一個8-bit的二進(jìn)制數(shù)循環(huán)右移偶數(shù)位,那么這個立即數(shù)是有效的,反之無效。
在上面的例子中,想要得到 r2 = 0xFFB 那么在匯編里就必須走兩步了,一步是無論如何無法到達(dá)的。
評論