ARM匯編中的立即數(shù)
在eVC編譯出的匯編代碼中我看到這樣的語(yǔ)句:
mov r2, #0xFF, 28 和 orr r2, r2, #0xB
這樣得到的結(jié)果時(shí) r2=#0xffb ,
他試圖更直接一點(diǎn)優(yōu)化成一句:MOV r2,#0xffb
但是這樣之后編譯就出了問(wèn)題:error A0092: no immediate rotate operand can be created: 4091
------------------------------------我是無(wú)辜的分割線--------------------------------
本文引用地址:http://www.ex-cimer.com/article/201611/317884.htm在 mov r2,#0xffb 這句中,不是MOV的用法出錯(cuò),而是立即數(shù)用法出錯(cuò)。
立即數(shù)的用法定義在Arm Architechture Reference Manual(簡(jiǎn)稱ARMARM)的A5-4頁(yè)開始
很重要的一段:
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頁(yè)中提到
shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
以及
Some values of
所以,綜上所述,首先解釋清楚了 mov r2,#0xFF,28 一句。28并不是第三個(gè)操作數(shù),而是和0xFF并在一起作為立即數(shù)使用,將0xFF循環(huán)右移28位。而這里必須強(qiáng)調(diào)右移XX位必須是個(gè)偶數(shù),因?yàn)樗鼘⒌扔?rotate_imm*2,那么在該指令的機(jī)器碼中rotate_imm = 14, 也就是在32-BIT的機(jī)器碼中第11到第8 bit = 1110B
然后再來(lái)看 mov r2,#0xFFB 的出錯(cuò)情況
0xFFB = 111111111011B,很顯然按照 shifter_operand = immed_8 Rotate_Right (rotate_imm * 2) 的公式, shifter_operand = 0xFFB時(shí)無(wú)法得到有效的 immed_8 和 rotate_imm, 所以編譯出現(xiàn)錯(cuò)誤 error A0092: no immediate rotate operand can be created: 4091 也可以理解了,它應(yīng)該是說(shuō)無(wú)法生成rotate_imm,實(shí)際上immed_8也是無(wú)法生成的。
關(guān)于立即數(shù)如何分解成immed_8和rotate_imm,可以參考上面給出的valid constants和invalid constants,簡(jiǎn)而言之,如果該立即數(shù)可以分解成一個(gè)8-bit的二進(jìn)制數(shù)循環(huán)右移偶數(shù)位,那么這個(gè)立即數(shù)是有效的,反之無(wú)效。
在上面的例子中,想要得到 r2 = 0xFFB 那么在匯編里就必須走兩步了,一步是無(wú)論如何無(wú)法到達(dá)的。
評(píng)論