2.ARM指令寻址方式
- 数据处理指令的操作数的寻址方式。
- 字及无符号字节的Load/Store指令的寻址方式。
- 杂类Load/Store指令的寻址方式。
- 批量Load/Store指令的寻址方式。
- 协处理器Load/Store指令的寻址方式。
通常数据处理指令的格式如下所示: <opcode>{<cond>}{S} <Rd>,<Rn>,<shifter_operand> 其中: <opcode> 是指令助记符,如ADD表示算术加操作指令。 {<cond>} 表示指令执行的条件。 {S} 决定指令的操作是否影响CPSR的值。 <Rd> 表示目标寄存器。 <Rn> 表示包含第1个操作数的寄存器。 <shifter_operand> 表示第2个操作数。 其有以下三种格式
-
- 立即数方式
-
- 寄存器方式
-
- 寄存器移位方式
- ASR 算术右移
- LSL 逻辑左移
- LSR 逻辑右移
- ROR 循环右移
- RRX 扩展的循环右移
2.2.1 数据处理指令的操作数的寻址方式
数据处理指令操作数的具体寻址方式有下面11种。
- #<immediate>
例:MOV R0,#0X10;将立即数0x10给R0
- <Rm>
例:MOV R0,R1;将R1的值放到R0
- <Rm>,LSL #<shift_imm>
例:MOV R0,R0,LSL #1;R0=R0*(2**1)
- <Rm>,LSL <Rs>
例:MOV R0,R0,LSL R1;R0=R0左移R1位后的值
- <Rm>,LSR #<shift_imm>
例:MOV R0,R0,LSL #1;R0=R0/(2**1)
- <Rm>,LS1R <Rs>
例:MOV R0,R0,LSL R1;R0=R0右移R1位后的值
- <Rm>,ASR #<shift_imm>
- <Rm>,ASR <Rs>
- <Rm>,ROR #<shift_imm>
- <Rm>,ROR <Rs>
- <Rm>,RRX
2.2.2 字及无符号字节的Load/Store指令的 寻址方式
种类型的Load/Store指令的寻址方式由两部分组成。 一部分为一个的基址寄存器;另一部分为一个地址偏移量。
基址寄存器可以为任一个通用寄存器; 地址偏移量可以有以下3种格式。立即数 寄存器 寄存器及一个移位常数 同样,寻址方式的地址计算方法有如下3种:偏移量方法 事先更新方法 事后更新方法 LDR指令的语法格式如下所示: LDR{<cond>}{B} {T}<Rd>,<address_mode> 其中,<address_mode>表示第2个操作数的内存地址,共有如下9种格式:
1.立即数+偏
- [<Rn>,#+/–<offset_12>]
例:LDR R0,[R0,#4];将内存单元R0+4中的字读取到R0中
2.寄存器+偏
- [<Rn>,+/–<Rm>]
例:LDR R0,[R0,R1];将内存单元R0+R1中的字读取到R0中
3.寄存器+移位+偏
- [<Rn>,+/–<Rm>,<shift>#<shift_imm>]
LDR R0 [R0,R1,LSL #1];将内存单元R0+R1*(2**1)中的数据读取到R0中
4.立即数+偏+事先访问
- [<Rn>,#+/–<offset_12>]!
例:LDR R0,[R0,#4];将内存单元R0+4中的字读取到R0中,同时R0=R0+4
5.寄存器+偏+事先访问
- [<Rn>,+/–<Rm>]!
例:LDR R0,[R0,R1];将内存单元R0+R1中的字读取到R0中,同时R0=R0+R1
- 寄存器+移位+事先访问
- [<Rn>,+/–<Rm>,<shift>#<shift_imm>]!
LDR R0 [R0,R1,LSL #1];将内存单元R0+R1*(2**1)中的数据读取到R0中,同时R0=R0+R1*(2**1)
- 立即数+事后访问
- [<Rn>],#+/–<offset_12>
LDR R0,[R1],#4;将内存单元R1中的数据读取到R0中,然后R0=R1+4
- 寄存器+事后访问
- [<Rn>],+/–<Rm>
LDR R0,[R1],R2;将内存单元R1中的数据读取到R0中,然后R0=R1+R2
9.寄存器+移位+事先访问
- [<Rn>],+/–<Rm>,<shift>#<shift_imm>
LDR R0,[R1],R2,LSL #2;将内存单元R1中的数据读取到R0中,然后R0=R1+R2*(2**2)
2.2.3 杂类Load/Store指令的寻址方式
杂类Load/Store指令包括:
- 操作数为半字(无符号数或带符号数)数据的Load/Store指令;
- 操作数为带符号的字节数据的Load 指令;双字的Load/Store指令。 这类指令的语法格式为: LDR|STR{<cond>}H|SH|SB|D <Rd>,<addressing_mode> 其中,<addressing_mode>是指令中内存单元的寻址方式,具体有以下6种格式:
- 立即数+偏
- [<Rn>,#+/–<offset_8>]
LDRSB R0,[R1,#4];将内存单元R1+4中的有符号字节数据读取到R0寄存器中;R0中高24位设置成该字节数据的符号位
- 寄存器+偏
- [<Rn>,+/–<Rm>]
STRH R0,[R1,R2];将R0中低16位数据保存内存单元(R1+R2)中
- 寄存器+移位+事先访问
- [<Rn>,#+/–<offset_8>]!
LDRSH R0,[R1,#4]!;将内存单元(R1+4)中字节数据读取到R0中;R0中高16位设置成该半字节的符号位,同时R1=R1+4
- 寄存器+事先访问
- [<Rn>,+/–<Rm>]!
LDRH R0,[R1,R2]!;将内存单元(R1+R2)中的半字数据读取到R0中;R0中高16位设置成0,同时R0=R1+R2
- 寄存器+移位+事后
- [<Rn>],#+/–<offset_8>
STRH R0,[R1],#4;将R0中低16位数据保存到内存单元R1中,然后(指令执行完后)R0=R1+4
- 寄存器+事后
- [<Rn>],+/–<Rm>
STRH R0,[R1],R2;将R0中低16位数据保存到内存单元R1中,然后(指令执行完后)R1=R1+R2
2.2.4 批量Load/Store指令的寻址方式
一条批量Load/Store指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。 其语法格式如下: DM|STM{<cond>}<addressing_mode> <Rn>{!}, <registers>{^} <addressing_mode>表示地址的变化方式,有以下4种方式。 IA (Increment After) 事后递增方式 IB (Increment Before) 事先递增方式 DA (Decrement After) 事后递减方式 DB (Decrement Before) 事先递减方式
2.2.5 协处理器Load/Store指令的寻址方式
一条协处理器Load/Store指令可以在ARM处理器和协处理器之间传输批量数据。 其语法格式如下: <opcode>{<cond>}{L} <coproc>,<CRd>,<addressing_mode> 其中,<addressing_mode>表示地址的变化方式,有以下4种格式: [<Rn>,#+/–<offset_8>*4] [<Rn>,#+/–<offset_8>*4]! [<Rn>],#+/–<offset_8>*4 [<Rn>],<option>