2. ARM指令分类及其寻址方式
2.1 ARM指令集概要介绍
2.1.1 ARM指令分类
-
跳转指令
-
数据处理指令
-
程序状态寄存器传输指令
-
Load/Store指令
-
协处理器指令
-
异常中断产生指令
2.1.2 ARM指令的一般编码格式
31-28 | 27-25 | 24-21 | 20 | 19-16 | 15-12 | 11-0 |
---|---|---|---|---|---|---|
cond | 001 | opcode | S | Rn | Rd | shifter_operand |
opcode:指令操作符编码
cond:指令执行的条件编码
S:决定指令的操作是否影响CPSR的值
Rd:目标寄存器编码
Rn:包含第一个操作数的寄存器编码
shifter_operand:表示第二操作数
一条典型的ARM指令语法格式如下所示:
2.1.3 ARM指令的条件码域
条件码 |
条件码助记符 | 含义 | CPSR中条件标志位值 |
---|---|---|---|
0000 | EQ | 相等 | Z =1 |
0001 | NE | 不相等 | Z =0 |
0010 | CS/HS | 无符号数大于/等于 | C=1 |
0011 | CC/LO | 无符号数小于 | C=0 |
0100 | MI | 负数 | N=1 |
0101 | PL | 非负数 | N=0 |
0110 | VS | 上溢出 | V=1 |
0111 | VC | 没有上溢出 | V=0 |
1000 | HI | 无符号数大于 | C=1且Z=0 |
1001 | LS | 无符号数小于等于 | C=0或Z=1 |
1010 | GE | 带符号数大于等于 | N=1且V=1 或 N=0且V=0 |
1011 | LT | 带符号数小于 | N=1且V=0 或 N=0且V=1 |
1100 | GT | 带符号数大于 | Z=0 且 N=V |
1101 | LE | 带符号数小于/等于 | Z=1或N!=V |
1110 | AL | 无条件执行 | |
1111 | AL | 该指令无条件执行 | ARMv5及以上版本 |
2.2 ARM指令寻址方式
-
数据处理指令的操作数的寻址方式
-
字及无符号字节的Load/Store指令的寻址方式
-
杂类Load/Store指令的寻址方式
-
批量Load/Store指令的寻址方式
-
协处理器Load/Store指令的寻址方式
2.2.1 数据处理指令的操作数的寻址方式
<shifter_operand>格式:
-
立即数方式
-
寄存器方式
-
寄存器移位方式
数据处理指令操作数的具体寻址方式:
-
#<immediate>
-
<Rm>
-
<Rm>, LSL #<shift_imm>
-
<Rm>, LSL <Rs>
-
<Rm>, LSR #<shift_imm>
-
<Rm>, LSR <Rs>
-
<Rm>, ASR #<shift_imm>
-
<Rm>, ASR <Rs>
-
<Rm>, ROR #<shift_imm>
-
<Rm>, ROR <Rs>
-
<Rm>, RRX
2.2.2 字及无符号字节的Load/Store指令的寻址方式
Load用于从内存中读取数据放入寄存器;Store指令用于将寄存器中的数据保存到内存。
ARM有两大类Load/Store指令:
-
用于操作32位的字类型数据以及8位无符号的字节类型数据
-
用于操作16位半字类型的数据以及8位的有符号字节类型的数据
Load/Store指令的寻址方式由两部分组成:
-
基址寄存器
-
地址偏移量
地址偏移量3种格式:
-
立即数
-
寄存器
-
寄存器及一个移位常数
-
寻址方式的地址计算方法:
-
偏移量方法
-
事先更新方法
-
事后更新方法
LDR指令的语法格式:
LDR {<cond>}{B} {T}<Rd>, <address_mode>
<address_mode>表示第2个操作数的内存地址,共有如下9种格式:
-
[<Rn>, #+/-<offset_12>]
内存地址address为基址寄存器值加上/减去偏移量
-
[<Rn>, +/-<Rm>]
内存地址address为基址寄存器值加上/减去索引寄存器Rm值
-
[<Rn>, +/-<Rm>, <shift>#<shift_imm>]
-
[<Rn>, #+/-<offset_12>]!
执行条件满足,生成的地址值写入基址寄存器Rn中,事先访问方式
-
[<Rn>, +/-<Rm>]!
-
[<Rn>, +/-<Rm>, <shift>#<shift_imm>]!
-
[<Rn>], #+/-<offset_12>
使用基址寄存器Rn的值作为实际内存访问的地址,最后将新的地址值写入基址寄存器Rn,事后访问方式
-
[<Rn>], +/-<Rm>
-
[<Rn>], +/-<Rm>, <shift>#<shift_imm>
2.2.3 杂类Load/Store指令的寻址方式
-
操作数为半字(无符号数或带符号数)数据的
-
操作数为带符号的字节数据的Load指令
-
双字的Load/Store指令
语法格式为:
LDR|STR {<cond>} H|SH|SB|D <Rd>, <address_mode>
其中,<address_mode>是指令中内存单元的寻址方式,有如下6种格式:
-
[<Rn>, #+/-<offset_8>]
-
[<Rn>, +/-<Rm>]
-
[<Rn>, #+/-<offset_8>]!
-
[<Rn>, +/-<Rm>]!
-
[<Rn>], #+/-<offset_8>
-
[<Rn>], +/-<Rm>
位B用于控制指令操作的数据类型
位L控制内存操作的方向
位S用于控制半字访问时数据类型
当S=0且H=0时,表示无符号的字节数据。
S=1且L=0表示带符号的Store指令
当R15用作基址寄存器Rn时,内存基地址位当前指令地址加8字节偏移量
2.2.4 协处理器Load/Store指令的寻址方式
协处理器Load/Store指令可以在ARM处理器和协处理器之间传输批量数据。语法格式如下:
<opcode>{<cond>}{L} <coproc>, <CRd>, <addressing_mode>
其中,<addressing_mode>表示地址的变化方式,格式:
-
[<Rn>, #+/-<offset_8>*4]
-
[<Rn>, #+/-<offset_8>*4]! 事先更新
-
[<Rn>], #+/-<offset_8>*4 事后更新
-
[<Rn>], <option>