首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

对ARM数据处理指令中#immed_8r的理解

对ARM数据处理指令中#immed_8r的理解

首先要感谢tekkamanninja所作博文http://blog.chinaunix.net/space.php?uid=20543672&do=blog&id=94265&page=1#comment关于ARM处理器中“8位位图”的理解分析》(阅读次数达到8000,壮观,敬仰),为我对这个问题的思考带来柠檬水滴入眼球一般的畅爽!见书中有如下描述“大多数ARM通用数据处理指令有一个灵活的第二操作数(flexible secondoperand)。”其中的#immed_8r的第二操作数形式让我百思不得其解。查到ZLG的课件(感谢)有如下图表:


#immed_8r这个立即数的要求是满足如上8位位图,即两点要求:
1·能用长度为8位的框框将这个数框起来。
错误示范:先假设#immed_8r值为0x101(0000000000000000 0000000100000001)红色加粗部分为9位,无法满足此要求,编译会出错。
2·这个数必须能由一个8位的常数循环右移偶数次得到。
错误示范:设#immed_8r值为0x102(0000000000000000 0000000100000010)假如把红色加粗部分看做8位常数框(满足要求1)。可以看出,这是经过奇数次循环右移得到的结果,不满足要求2。
0x102(00000000 00000000 0000000100000010)假如试图满足要求2,以红色加粗部分看做是由原常数循环右移0次(0、2、4、……、30都是偶数次,后面将解释)得到,则会不满足要求1(9位)。所以编译也会报错。

上面的要求使得#immed_8r不能直接取遍32位所有数(是不是ARM的所有立即数都有这个要求吗?对寄存器的立即数操作呢?后来(11.11.16)学习到:伪指令LDR{cond}register,=[expr |label-expr]貌似能够存入任意32位数,但是具体限制又是什么呢?),为什么不能一步到位,下面根据参考的博文来分析:
ARM的数据处理指令语法通常为(以AND、ORR、EOR、BIC为例):op {cond}{S}Rd,Rn{,Operand2}
但其实它的ARM的指令编码如下:


其中[7:0]位就是要求8位的原因,留给立即数数值的位数只有8位。而[11:8]位rotate是循环(右移)次数,是4位的。
我设想可能设计者是这样考虑的:就算12个位全部用来存立即数,也只能表示2^12次个数,和2^32次个数相差很远。于是使用循环(右移)次数标记来与8位立即数组合。
但假如每+1,只右移1位的话,全部加满也才右移了2^4=16位(0~15)。所以设定每+1标记,循环右移2位,这样就能移遍32位(0~15X 2)。
即便是这样,也不能表示完2^32个值,就如同上面的错误示范的数是不符合要求的。这就有了bootload中这样的语句(我复制的是6410的,书是ARM7的,看来学这点一直没变):
       bic       r1, r1, #0xff00
       bic       r1, r1, #0xff

组合起来,才能表示#0xffff(指令还没学完……只能说到这里)

ARM门槛高,知识点多而且细……大家继续努力吧~!
继承事业,薪火相传
返回列表