教你快速判断ARM指令中合法立即数

arm立即数弄不好就是error 什么立即数是合法的呢?怎么才能快速判断?请看后文,写得漂亮啊!

地址:http://www.cnblogs.com/walzer/archive/2006/02/05/325610.html   万分感谢作者呀!

作者:Walzer
日期:2005.2.4

同事遇到这样一个问题:
在eVC编译出的汇编代码中我看到这样的语句:
mov       r2, #0xFF, 28 和 orr       r2, r2, #0xB
这样得到的结果时 r2=#0xffb ,
他试图更直接一点优化成一句:MOV r2,#0xffb
但是这样之后编译就出了问题:error A0092: no immediate rotate operand can be created: 4091

------------------------------------我是无辜的分割线--------------------------------

在 mov r2,#0xffb 这句中,不是MOV的用法出错,而是立即数用法出错。

立即数的用法定义在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页中提到
<immediate> Specifies the immediate constant wanted. It is encoded in the instruction as an 8-bit immediate (immed_8) and a 4-bit immediate (rotate_imm), so that <immediate> is equal to the result of rotating immed_8 right by (2*rotate_imm) bits.

shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)

以及
Some values of <immediate> have more than one possible encoding. When more than one encoding is available, an assembler needs to choose the correct one to use. For more precise control of the encoding, the instruction fields can be specified directly by using the syntax: #<immed_8>, <rotate_amount>

所以,综上所述,首先解释清楚了 mov r2,#0xFF,28 一句。28并不是第三个操作数,而是和0xFF并在一起作为立即数使用,将0xFF循环右移28位。而这里必须强调右移XX位必须是个偶数,因为它将等于rotate_imm*2,那么在该指令的机器码中rotate_imm = 14, 也就是在32-BIT的机器码中第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, 所以编译出现错误 error A0092: no immediate rotate operand can be created: 4091 也可以理解了,它应该是说无法生成rotate_imm,实际上immed_8也是无法生成的。

关于立即数如何分解成immed_8和rotate_imm,可以参考上面给出的valid constants和invalid constants,简而言之,如果该立即数可以分解成一个8-bit的二进制数循环右移偶数位,那么这个立即数是有效的,反之无效。

在上面的例子中,想要得到 r2 = 0xFFB 那么在汇编里就必须走两步了,一步是无论如何无法到达的。

*******************************下面加上自己的理解****************************************
看了这篇文章后我一直 在想一个问题:如何去判断一个立即数是否合法呢?

自己总结了一个方法不知道是否全面,请高手指教

1.如十六进制数在0x00到0xFF之间,则它一定是合法的

1.若十六进制数>0XFF则将十六进制的数转化成十进制

2.如果这个十进制数能够被4整除则这个十六进制的立即数和合法的,否则是非法的

3例如:0x101=257/4=64.25 非法

            0x104=260/4=65 合法

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值