ARM指令集之数据处理指令寻址方式

本文详细介绍了ARM指令集中数据处理指令的寻址方式,包括立即数寻址、寄存器寻址以及各种类型的逻辑移位和算数移位寻址。特别指出,应避免使用R15作为寻址方式,因为它可能因流水线技术导致地址变化。对于不能直接用立即数表示的数值,可以利用ldr伪指令加载到寄存器后,采用寄存器寻址。
摘要由CSDN通过智能技术生成

所谓的寻址方式,是指当一个指令中的操作数涉及内存访问时,那么指令已什么样的方式来确定内存的地址。

ARM的寻址方式分好几类,这篇笔记记录了数据处理类指令的寻址方式。

数据处理指令

常见的数据处理指令如下表所示,它们支持相同的寻址方式。

助记符说明实现逻辑
MOV数据传送Rd = Rn(Rn可能需要运算)
MVN数据取反传送Rd = ~Rn(Rn可能需要运算)
ADDRd = Rn + op2
ADC带进位加Rd = Rn + op2 + C
AND逻辑加Rd = Rn && op2
EOR逻辑异或Rd = Rn ^ op2
SUBRd = Rn - op2
SBC带进位的减Rd = Rn - op2 + C - 1
RSB反转减Rd = op2 - Rn
RSC带进位的反转减Rd = op2 - Rn + C - 1
TST测试Rn && op2的结果更新标志位
TEQ测试相等Rn ^ op2的结果更新标志位
CMP比较Rn - op2的结果更新标志位
CMN符数比较Rn + op2的结果更新标志位
ORR逻辑或Rd = Rn || op2
BIC位清零Rd = Rn && ~(op2)

寻址方式

ARM为数据处理指令支持11种寻址方式。

语法说明
1#<immediate>立即数寻址
2<Rm>寄存器寻址
3<Rm>, LSL #<shift_imm>寄存器逻辑左移立即数个位
4<Rm>, LSL <Rs>寄存器逻辑左移寄存器个位
5<Rm>, LSR #<shift_imm>寄存器逻辑右移立即数个位
6<Rm>, LSR <Rs>寄存器逻辑右移寄存器个位
7<Rm>, ASR #<shift_imm>寄存器算数右移立即数个位
8<Rm>, ASR <Rs>寄存器算数右移寄存器个位
9<Rm>, ROR #<shift_imm>寄存器循环右移立即数个位
10<Rm>, ROR <Rs>寄存器循环右移寄存器个位
11<Rm>, RRX寄存器扩展循环右移
  1. 逻辑移位指的是移位后,空余位用0补齐;
  2. 算数移位指的是移位后,空余位用原Rm[31]的值补齐;
  3. 循环移位不涉及补齐;

注:尽量避免用R15来用作上述寻址方式,因为流水线技术的原因,R15的值是当前指令的地址加8(3级流水线),这种变化不利于程序编写,此外某些情况下并不能使用R15。

1. 立即数寻址

立即数寻址时,每个立即数由一个8位的常数循环右移偶数位得到,其中循环右移的位数是由一个4bit数字*2表示。所以,并不是每一个32位的立即数都能通过这种方式指定,只有通过这种方式能够构造得到的立即数才是合法的。

立即数寻址的伪代码如下:

语法:#<immediate>

shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
if rotate_imm == 0 then
	shifter_carry_out = C flag
else
	shifter_carry_out = shifter_operand[31]

心得:首先,个人理解没有必要去研究到底一个立即数是否合法,编码时可以直接让汇编器帮忙检查;并且如果无法表示该立即数,我们可以通过ldr伪指令来将任意一个立即数传送到寄存器中,然后使用寄存器寻址方式来代替立即数寻址。

2. 寄存器寻址

语法: <Rm>

shifter_operand = Rm
shifter_carry_out = C flag

3. 寄存器逻辑左移立即数寻址

语法:<Rm>, LSL #<shift_imm>

if shift_imm == 0 then
	shifter_operand = Rm
	shifter_carray_out = C flag
else
	shifter_operand = Rm Logical_Shift_Left shift_imm
	shifter_carry_out = Rm[32 - shift_imm]

4. 寄存器逻辑左移寄存器寻址

语法:Rm>, LSL <Rs>

if Rs[7:0] == 0 then
	shifter_operand = Rm
	shifter_carray_out = C flag
elif Rs[7:0] < 32 then
	shifter_operand = Rm Logical_Shift_Left Rs[7:0]
	shifter_carry_out = Rm[32 - Rs[7:0]]
elif Rs[7:0] == 32 then
	shifter_operand = 0
	shifter_carry_out = Rm[0]
else
	shifter_operand = 0
	shifter_carry_out = 0

5. 寄存器逻辑右移立即数寻址

语法:<Rm>, LSR #<shift_imm>

if shift_imm == 0 then
	shifter_operand = 0
	shifter_carray_out = Rm[31]
else
	shifter_operand = Rm Logical_Shift_Right shift_imm
	shifter_carry_out = Rm[shift_imm - 1]

6. 寄存器逻辑右移寄存器寻址

语法:<Rm>, LSR <Rs>

if Rs[7:0] == 0 then
	shifter_operand = Rm
	shifter_carray_out = C flag
elif Rs[7:0] < 32 then
	shifter_operand = Rm Logical_Shift_Right Rs[7:0]
	shifter_carry_out = Rm[Rs[7:0] - 1]
elif Rs[7:0] == 32 then
	shifter_operand = 0
	shifter_carry_out = Rm[31]
else
	shifter_operand = 0
	shifter_carry_out = 0

7. 寄存器算数右移立即数寻址

语法:Rm>, ASR #<shift_imm>

if shift_imm == 0 then
	shifter_carray_out = Rm[31]
	if Rm[31] == 0 then
		shifter_operand = 0
	else
		shifter_operand = 0xFFFF_FFFF
else
	shifter_operand = Rm Arithmetic_Shift_Right shift_imm
	shifter_carry_out = Rm[shift_imm - 1]

8. 寄存器算数右移寄存器寻址

语法:<Rm>, ASR <Rs>

if Rs[7:0] == 0 then
	shifter_operand = Rm
	shifter_carray_out = C flag
elif Rs[7:0] < 32 then
	shifter_operand = Rm Arithmetic_Shift_Right Rs[7:0]
	shifter_carry_out = Rm[Rs[7:0] - 1]
elif Rs[7:0] == 32 then
	shifter_operand = 0
	shifter_carry_out = Rm[31]
else
	shifter_carry_out = Rm[31]
	if Rm[31] == 0 then
		shifter_operand = 0
	else
		shifter_operand = 0xFFFF_FFFF

9. 寄存器循环右移立即数寻址

语法:<Rm>, ROR #<shift_imm>

if shift_imm == 0 then
	见“”介绍
else
	shifter_operand = Rm Rotate_Right shift_imm
	shifter_carry_out = Rm[shift_imm - 1]

10. 寄存器循环右移寄存器寻址

语法:<Rm>, ROR <Rs>

if Rs[7:0] == 0 then
	shifter_operand = Rm
	shifter_carray_out = C flag
elif Rs[4:0] < 32 then
	shifter_operand = Rm
	shifter_carray_out = Rm[31]
else
	shifter_operand = Rm Rotate_Right Rs[4:0]
	shifter_carry_out = Rm[Rs[4:0]- 1]

11. 寄存器扩展循环右移寻址

语法:<Rm>, RRX

shifter_operand = (C Flag Logical_Shift_Left 31) || (Rm Logical_Shift_Right 1)
shifter_carry_out = Rm[0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值