ARM指令格式以及第二个操作数的immed_8r形式
基本语法格式
编码指令格式
ARM是三地址指令格式,指令的基本格式如下:
其中<>号内的项是必须的,{}号内的项是可选的。各项的说明如下:
Opcode:指令助记符;
cond:执行条件;
S:是否影响CPSR寄存器的值;
Rd:目标寄存器;
Rn:第1个操作数的寄存器;
operand2:第2个操作数;
第二个操作数(12位)
灵活的使用第2个操作数"operand2"能够提高代码效率。它有如下的形式:
- #immed_8r——常数表达式(立即数-immediate operand);
- Rm——寄存器方式;
- Rm,shift——寄存器移位方式;
#immed_8r——常数表达式
该常数必须对应8位位图,即一个8位的常数通过循环右移偶数位得到。
这里需要注意的点:
- 8位数
- 循环右移偶数位
理解:ARM需要使用12位的编码来表示32位数。那么如何实现这一点呢?
8位存数据,4位存移位的次数(实际是移位数÷2)
理解:4位只有16种可能值,而32位数可以循环移位32次(32种可能),并且为什么必须是右移偶数位呢,而不能是奇数位呢?
为什么会有立即数这样的规定呢,这是由于所有的ARM指令是精简指令集,指令长度固定都是32位,对于ARM数据处理指令自然也是一样。数据处理指令大致可包含3类,数据传送指令、数据算术逻辑运算指令和数据比较指令。在以条ARM数据处理指令中,除了要包含处理的数据值外,还要标识ARM命令名称,控制位,寄存器等其他信息。
这样在一条ARM数据处理指令中,能用于表示要处理的数据值的位数只能小于32位。 ARM在指令格式中设定,只能用指令机器码32位中的低12位来表示要操作的常数。ARM处理器是按32位来处理数 据的,ARM处理器处理的数据是32位,如果简单的用这12位来表示,显然范围太小了,为了扩展到32位,因此使用了 构造的方法,在12位中用8位表示基本数据值,用4位表示位移值,通过用8位基本数据值往右循环移动4位位移值×2次,来表示要操作的常数。这里要强调终的循环次数是4位位移值乘以2得到的,所以得到的终循环次数肯定是一个偶数,为什么要乘以2呢,实质还是因为范围不够,4位表示位移次数,最大才15次,加上8位数据还是不够32位,这样只能通过ALU的内部结构设计将4位位移次数乘以2,这样就能用12位表示32位常数了。 通过循环偶数位得的到操作数,扩大了操作数的范围,但也带来了问题,并不是每个数据都能通过8位基本数据循 环移动偶数为得到,如果你在ARM数据处理指令中使用的操作数,不是立即数。
理解:为什么是右移?
arm中只有循环右移
理解:立即数能表示所有的32位数吗?
不能,只能表示32位数中的一部分,不是每个数都能通过8位基本数据循环移动偶数次得到。