ARM指令的格式:
ARM是32位的处理器,其指令格式自然也是32位,其格式如下:
<opcode> { <cond> } {S} <Rd>, <Rn> {, <operand2> }
opcode操作码:指令助记符,如LDR,STR等。
cond可选的条件码:执行条件,如EQ,NE等。
S可选后缀:若指定“S”,则根据指令执行结果更新CPSR中的条件码。
Rd目标寄存器。
Rn存放第一操作数的寄存器。
operand2第二操作数。
ARM指令代码一般分成5个域区,
第一个域区[31:28]是条件码部分,4位共有16种条件组合.
第二个域区[27:20]是指令代码部分.除指令编码外,还包括后缀编码和指令特征位
第三个域区[19:16]是4位的地址基址部分Rn.为R0到R15共16个寄存器编码.
第四个域区[15:12]是4位的目标或源寄存器Rd域.为R0到R15共16个寄存器编码
第五个域区[11: 0]是地址偏移或操作寄存器,操作数区。
用以下例解释:LDMIA R5,{R2,R7,R8}
1110(条件码) 100(指令编码) 01001(其他) 0101(基址地址R5) 0000 0001(R8) 1000(R7) 0100(R2)
ARM指令可选后缀:
S后缀
S后缀的含义是,使用S后缀后,指令执行后程序状态寄存器的条件标志位将刷新;不时候S后缀时,指令执行后程序状态寄存器的条件标志位将不发生变化。如 :
ADD R3, R5,R8 R3<---R5+R8,没使用S后缀,条件标志位将不发生变化。
ADDS R3, R5,R8 R3<---R5+R8,使用S后缀,条件标志位根据结果刷新。
注:有的指令不使用S后缀,也可以刷新条件标志位。比如CMP,CMN,TST等。
!后缀
!后缀的含义是:在指令的地址表达式中含有!后缀时,指令执行后,基址寄存器中的地址将会发生变化,变化的结果如下:
基址寄存器中的地址值(指令执行后)= 指令执行前的值+地址偏移量
如果指令不含!后缀,则地址值不会发生变化。
LDMIA R3,[R0,#04] ; R3<---[R0+#04],没有使用!后缀。
LDMIA R3,[R0,#04] ! ; R3<---[R0+#04],使用!后缀
R0<--R0+#04
注!后缀不能用在R15的后面。
B后缀
B后缀的含义是:指令所涉及的数据是一字节,不是一字或者半字。
LDR R4,[R0,#12] R4<----[R0+0x12]指令传送一个字
LDRB R4, [R0,#12] R4<----[R0+0x12]指令传送一个字节
T后缀
T后缀是一个很特殊的后缀,含义是:指令在特权模式下对存储器的访问,将被存储器看作是用户模式的访问。例如:
LDRT R4,[R5] ; R4<---[R5]T模式。
ARM指令的条件后缀
条件后缀的用途:在指令执行前先判断条件是否满足。满足执行本条指令,不满足跳过执行下一条指令例如:
ADDEQ R4,R3,#0x01 在Z零标志位等于零的时候(Z=0),R4<---R3+1被测试的条件标志位有 Z,C,N和V
N负数或小于
C进位或借位或扩张
Z零
V溢出
以上4位在CPSR或SPSR中。
ARM的条件码表
编码 | 后缀助记符 | 标志位 | 定义 |
0000 | EQ | Z=1 | 相等 |
0001 | NE | Z=0 | 不相等 |
0010 | CS | C=1 | 无符号大于或者等于 |
0011 | CC | C=0 | 无符号小于 |
0100 | MI | N=1 | 负值 |
0101 | PL | N=0 | 正值或0 |
0110 | VS | V=1 | 溢出 |
0111 | VC | V=0 | 无溢出 |
1000 | HI | C=1且Z=0 | 无符号大于 |
1001 | LS | C=0或Z=1 | 无符号小于或等于 |
1010 | GE | N和V相同 | 有符号大于或等于 |
1011 | LT | N和V不同 | 有符号小于 |
1100 | GT | Z=0且N等于V | 有符号大于 |
1101 | LE | Z=1或N不等于V | 有符号小于或等于 |
1110 | AL | 无条件 | 无条件 |