ARM的合法立即数与非法立即数

一、前言

首先从ARM指令系统的语法格式说起:

一条ARM指令语法格式分为如下几个部分:

<opcode>{<cond>}{S} <Rd>,<Rn>{,<shifter_operand>}


其中,<>内的项是必须的,{}内的项是可选的,如<opcode>是指令助记符,是必须的,而{<cond>}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。

(1)Opcode   指令助记符,如LDR,STR 等

(2)Cond       执行条件,如EQ,NE 等

(3)S           是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响

(4)Rd          目标寄存器

(5)Rn          第一个操作数的寄存器

(6)shifter_operand      第二个操作数


仔细看表格中的shifter_operand所占的位数:12位。要用一个12位的编码来表示任意的32位数是绝对不可能的

(12位数有2^12种可能,而32位数有2^32种)。

但是又要用12位的编码来表示32位数,怎么办?

只有在表示数的数量上做限制。通过编码来实现用12位的编码来表示32位数。

在12位的shifter_operand中:8位存数据,4位存移位的次数。

8位存数据:解释了“该常数必须对应8位位图”。

4位存移位的次数:解释了为什么只能移偶数位。4位只有16种可能值,而32位数可以循环移位32次(32种可

能),那就只好限制:只能移偶数位(两位两位地移,好像一个16位数在移位,16种移位可能)。这样就解决了

能表示的情况是实际情况一半的矛盾。

所以对#immed_8r常数表达式的限制是解决指令编码的第二个操作数位数不足以表示32位操作数的无奈之举,但

在我看来:这个可以说是聪明的做法。因为如果直接用12位数来表示32位操作数,只能表示0 到(2^12-1)。大

于(2^12-1)的数就没办法表示了。而且细细想来“8位存数据,4位存移位的次数”,应该是最好的组合了(我并

未想过所有的组合,只是顺便试了几个)。


二、合法立即数

在 ARM 数据处理指令中, 当参与操作的第二操作数为立即数时, 每个立即数都是采用一个8位的常数循环右移偶数

位而间接得到(关于循环移位,其实arm中只有循环右移ROR), 其中循环右移的位数有一个4位二进制的2倍表

示. 

则有效立即数可表示为: 

<immediate> = immed_8循环右移(2×rotate_imm)位. 

其中: 

<immediate> 代表立即数,

 immed_8 代表8位常数,,

 rotate_imm 代表4位的循环右移值. 

这样一来出现了一个问题: 尽管表示的范围变大了, 但是12位所能表现的数字的个数是一定的. 因此, ARM 规定并不

是所有的32位常数都是合法的立即数, 只有通过上面的构造方法得到的才是合法的立即数, 编译的时候才不会报错.


三、编译器的处理方式

按照上面的构造方法,一个合法的立即数可能有多种编码方式,如0X3f0是一个合法的立即数,它可以采用下面的

两种编码方式:

    immed_8=0X3f,rotate_imm=0xe 或者

    immed_8=0Xfc,rotate_imm=0xf 

    但是,由于这种立即数的构造方法包含了循环右移操作,这将会影响CPSR的C位,因此,同一个合法的立即数

采用了不同的编码方式,将会使某些指令的执行产生不同的结果,这是不允许的,ARM汇编编译器按照下面的规

则来产生立即数的编码:

    1:当立即数数值在 0 和 0Xff 范围时,令 immed_8=<immediate>,rotate_imm=0

    2:其他情况下,汇编编译器选择使rotate_imm数值选择最小的编码方式。

四、如何判断一个数是合法立即数还是非法立即数

1.判断一个数是否符合8位位图的原则, 首先看这个数的二进制表示中1的个数是否不超过8个. 如果不超过8个, 再看

这n个1(n<=8)是否能同时放到8个二进制位中, 如果可以放进去, 再看这八个二进制位是否可以循环右移偶数位得到

我们欲使用的数. 如果可以, 则此数符合8位位图原理, 是合法的立即数. 否则, 不符合.

2.无法表示的32位数, 只有通过逻辑或算术运算等其它途径获得了. 比如0xffffff00, 可以通过0x000000ff按位取反得到.

五、编程使用

其实你没必要一个一个的算,只要利用LDR伪指令就可以了,例如:ldr r1, =12345678

编译器自然会给你做工作,现实的编程中应该也是这个居多吧

 

http://blog.sina.com.cn/s/blog_7ea827fe0100torx.html

http://www.cnblogs.com/walzer/archive/2006/02/05/325610.html

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值