立即寻址
立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数,这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。例如以下指令:
ADD R0,R0,#1 /*R0←R0+1*/
ADD R0,R0,#0x3f /*R0←R0+0x3f*/
立即数,要求以“#”为前缀,对于以十六进制表示的立即数,还要求在“#”后加上“0x”,对于以二进制表示的立即数,还要求在“#”后加上“0b” ,对于以十进制表示的立即数,还要求在“#”后加上“0d”或者缺省 。
立即数的表示
(1)8位立即数的表示
- 8位立即数用“#”+数字直接表示。
(2)32位立即数的表示
由于32位立即数在指令中占用32个位,如果直接表示,则将导致ARM指令编码的长度超过32位,为了减小编码长度,32位立即数采用移位间接表示法。
所谓移位间接表示法就是当指令中操作数为32位立即数时,该立即数必须采用一个8位常数然后通过偶数次的循环右移 得到,这时候,假设这个立即数immediate, 8位常数位immed_8,循环移位位数为2*rotate_imm,那么,这个立即数可以表示成:
immediate=immed_8 循环右移(2\*rotate_imm)
有效立即数问题
采用移位间接表示时,在指令里面,这个32位的立即数 immediate就可以用一个12位的编码(4位rotate_imm , 8位immed_8 )来表示。如:
MOV R0,#0x0000F200 ; 编码为:E3A00CF2
MOV R1,#0x00110000 ; 编码为:E3A01811
MOV R4,#0x00012800 ; 编码为:E3A04B4A
#0x00012800 = ob0001 00 10 10 00 0000 0000
这种编码算法的缺点是,并不是每一个32位常数都是一个合法的立即数,只有通过上述构造方法能够得到的32位立即数才是合法的立即数。如:0x0000F200,0x00110000,0x00012800都是合法的立即数,而0x1010、0x00102或0FF1000等都不是合法的立即数。
#0x0001010 = ob0001 0000 0001 0000
#0x0000102 = ob0000 0001 0000 0010
#0xFF1000 = ob1111 1111 0001 0000 0000 0000
寄存器寻址
寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。以下指令:
ADD R0,R1,R2 /*R0←R1+R2*/
该指令的执行效果是将寄存器R1和R2的内容相加,其结果存放在寄存器R0中。
寄存器为第2操作数的移位操作
当ARM指令的数据处理指令中参与操作的第2操作数为寄存器型时,可选择是否对该操作数进行移位操作,即:“Rm,”,其中,Rm为第2操作数寄存器,为移位类型(LSL,LSR,ASL,ASR,ROR或RRX)和移位位数。
移位位数可以是5位立即数或寄存器(Rs)。在指令执行时,移位后的数作为第2操作数参与运算,如:
ADD R3,R2,R1,LSR #2 ;R3←R2+R1÷4
ADD R3,R2,R1,LSR R4 ;R3←R2+R1÷2R4
而第2操作数寄存器的内容并不发生变化。
另外,只有寄存器作为第2操作数时,才能进行这样的移位,否则,不允许进行这样的移位。
第2操作数的移位方式
ARM可执行的移位操作有:
- LSL:逻辑左移,空出的最低位填0
- LSR:逻辑右移,空出的最高位填0
- ASL:算术左移,空出的最低位填0
- ASR:算术右移,如果被移位的数是有符号数,则空出的最高位填符号位。
- ROR:循环右移,移出的最低位填入空出的最高位
- RRX:带扩展的循环右移,右移一位,空出最高位填C,移出最低位进C。这种移位方式无需指定移位位数。
参考文献:
孟祥莲.嵌入式系统原理及应用教程(第2版)[M].北京:清华大学出版社,2017.