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

where一棵树上钓活how

where一棵树上钓活how

ARM指令格式
指令基本格式:
     <opcode>{<cond>}{S} <Rd>,<Rn>{,<operand2>}
1、<>内的项是必须的,{}内的项是可选的,cond若不附指令后使用默认条件AL(无条件执行)。2、opcode:指令助记符,如LDR,STR等;3、cond:执行条件,如EQ,NE等;4、S:是否影响CPSR寄存器的值;5、Rd:目标寄存器;6、Rn:第一个操作数的寄存器;7、operand2:第二个操作数;ARM指令中,灵活使用第二个操作数可提高代码效率,第二个操作数的形式有:
     √#immed_8r   ——常数表达式;
     √Rm                ——寄存器方式;
     √Rm,shift     ——寄存器移位方式;
#immed_8r:
    该常数必须对应8位位图(即首尾两个"1"bit间的间距为6bits且该常数通过循环左移偶数位所有bit=1的位必集中在低8bits)。如 0x1FE、511、0xFFFF、0x1010、0xF0000010为非法常量,0x3FC、0、0xF0000000、200、 0xF0000001为合法常量。
利用这种转换巧妙的实现了:在32bits的ARM指令代码中集成32bits的立即数(常数)。如立即寻址的 数据处理指令的指令代码为:xxxx001a aaaSnnnn ddddrrrr bbbbbbbb,则其第二个操作数op2=#b,ROR #2r,由op2到指令码的转换经编译器完成。Rm:
    在寄存器方式下,第二个操作数即寄存器的数值;
Rm,shift:
    在寄存器移位操作方式下,将寄存器的移位结果作为操作数,但Rm的值保持不变,移位方法有下:    其中n取值一般在1--31之间。 8、The ARM instruction set: 9、指令条件码:
关于ARM处理器中“8位位图”的理解分析
http://hi.baidu.com/dlutstone/blog/item/f8455bc37b68ee3de5dd3b4d.html
在ARM处理器的汇编语言中,对指令语法格式中的<shifter_operand>的常数表达式有这样的规定:“该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。”
首先从ARM指令系统的语法格式说起。
一条ARM指令语法格式分为如下几个部分:
<opcode>{<cond>}{S} <Rd>,<Rn>{,<shifter_operand>}
其中,<>内的项是必须的,{}内的项是可选的,如<opcode>是指令助记符,是必须的,而{<cond>}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。
Opcode   指令助记符,如LDR,STR 等
Cond       执行条件,如EQ,NE 等
       S           是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响
       Rd          目标寄存器
Rn          第一个操作数的寄存器
shifter_operand      第二个操作数

其指令编码格式如下:
31-28
27-25
24-21
20  
19-16
15-12
11-0 (12位)
cond
001
opcode
S
Rn
Rd
shifter_operand

当第2 个操作数的形式为:#immed_8r常数表达式时“该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。”
其意思是这样:#immed_8r在芯片处理时表示一个32位数,但是它是由一个8位数(比如:01011010,即0x5A)通过循环移位偶数位得到(1000 0000 0000 0000 0000 0000 0001 0110,就是0x5A通过循环右移2位(偶数位)的到的)。
而1010 0000 0000 0000 0000 0000 0001 0110,就不符合这样的规定,编译时一定出错。因为你可能通过将1011 0101循环右移位得到它,但是不可能通过循环移位偶数位得到。
1011 0000 0000 0000 0000 0000 0001 0110,也不符合这样的规定,很明显:1 0110 1011 有9位。
为什么要有这样的规定?
那位大哥的理解是(小呆:这个的确是很有道理):
要从指令编码格式来解释(这就是我为什么一开始讲的是指令编码格式),仔细看表格中的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位存移位的次数”,应该是最好的组合了(我并未想过所有的组合,只是顺便试了几个)。
继承事业,薪火相传
返回列表