ARM指令寻址方式之: 数据处理指令的寻址方式
4,ROR r0
4.1.4 寻址方式分类详解
数据处理指令的寻址方式根据<shifter_operand>的不同,相应的分为11种。详见表4.1。下面对各类寻址方式进行详细说明。
1.#<immediate>
(1)编码格式
指令的编码格式如图4.2所示。
图4.2 数据处理指令--立即数寻址编码格式
立即数寻址为数据处理指令提供了一个可直接操作的立即数。立即数的生成方法见前面章节介绍。如果移位值为0,则移位进位值为程序状态寄存器CPSR的C标志位;否则,为32-bit立即数的bit[31]。
(2)操作伪代码
Shifter_operand = immed_8 Rotate_Right (rotate_imm*2)
if rotate_imm == 0 then
shifter_carry_out = C flag
else /* rotate_imm != 0*/
shifter_carry_out = shifter_operand[31]
(3)说明
① 并不是所有的32-bit立即数都是可以使用的合法立即数。只有那些通过将一个8-bit的立即数循环右移偶数位可以得到的立即数才可以在指令中使用。
② 有些立即数可以通过不止一种方法得到。由于立即数的构造方法中移位包含了循环操作,而循环移位操作会影响CPSR的条件标志位C。因此,同一个合法的立即数由于采用了不同的编码方式,将使这些指令的执行产生不同的结果,这是不能允许的。ARM汇编器按照下面的规则来生成立即数的编码。
· 当立即数数值在0和0xFF范围时,令immed_8=<immediate>,immed_4=0。
· 其他情况下,汇编编译器选择使用immed_4数值最小的编码方式。
③ 为了更精确地控制立即数的生成,可以使用下面的语法格式控制立即数的生成。
#<immed_8>,<rotate_amout>
其中,<rotate_amout> = 2*rotate_imm
(4)举例
SUBS r0,r0,#1 ;寄存器r0中的数值减1,结果保存到r0
MOV r0,#0xff00 ; 0xff00 → r0 ;将立即数0xff00放入r0保存
2.<Rm>
(1)编码格式
指令的编码格式如图4.3所示。
图4.3 数据处理指令--寄存器寻址编码格式
指令的操作数即为寄存器中的数值。移位寄存器的进位为程序状态寄存器CPSR的C标志位。
指令的语法格式为:<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>
(2)操作伪代码
Shifter_operand = Rm
Shifter_carry_out = C Flag
(3)说明
① 从指令的解码格式来看,寄存器寻址方式和使用立即数逻辑左移寻址解码格式是相同的,只是其移位数为0。
② 如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。
(4)举例
MOV r1,r2 ; r2 → r1
SUB r0,r1,r2 ; r1 – r2 → r0
3.<Rm>, LSL #<shift_imm>
(1)编码格式
指令的编码格式如图4.4所示。
图4.4 数据处理指令--立即数逻辑左移寻址编码格式
指令的操作数为寄存器Rm的数值逻辑左移shift_imm位。左移的范围在0到31之间。左移移出的位用0补齐。进位标志位是最后移出的位(如果移位数为0,则为C标志位)。
指令的语法格式为:<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,LSL #<shift_imm>,其中:
· <Rm>为进行逻辑左移操作的寄存器;
· LSL为逻辑左移操作标识;
· <shift_imm>为逻辑左移位数,范围为0~31。
(2)操作伪代码
if shift_imm == 0 then /*执行寄存器操作*/
shifter_operand = Rm
shifter_carry_out = C flag
else /*移位寄存器大于零*/
shifter_operand = Rm logical_shift_left shift_imm
shifter_carry_out = Rm[32 – shift_imm]
(3)说明
① 如果移位立即数<shift_imm> =0,则该寻址方式为立即数直接寻址。
② 如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。
(4)举例
SUB r0,r1,r2,LSL #10 ;r1的值减去r2的值左移10bit,结果放到r0寄存器
MOV r0,r2,LSL #3 ;r2的值左移3bit,结果放入r0,即r0 = r2×8
4.<Rm>, LSL <Rs>
(1)编码格式
指令的编码格式如图4.5所示。
图4.5 数据处理指令--寄存器逻辑左移寻址编码格式
寄存器逻辑左移十分适合寄存器值乘2的倍数操作。
这个指令是将寄存器Rm的值逻辑左移一定的位数。位移的位数由Rs的最低8位bit[7∶0]决定。Rm移出的位用0补齐。进位值是移位寄存器最后移出的位,如果移位数大于0,则进位值为0。
(2)语法格式
<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,LSL <Rs>
其中:
· <Rm>为指令被移位的寄存器;
·
- 数据处理指令之:AND逻辑与指令(08-13)
- 数据处理指令之:SUB减操作指令(08-13)
- 数据处理指令之: RSB减翻转指令(08-13)
- 数据处理指令之: ADD加操作指令(08-13)
- 数据处理指令之: TST测试指令(08-13)
- 数据处理指令之: CMP比较指令(08-13)