* 六个操作模式
User Mode --- 用户模式,大部分任务在此模式下运行
FIQ --- 快速中断模式
IRQ --- 普通中断模式
Supervisor --- 特权模式,软件中断或者复位进入
Abort --- 数据访问错误模式
Undef --- 指令未定义模式
* ARM V4添加第七中模式
System --- 系统特权模式,与user mode使用同样的寄存器
* 共37个寄存器:
r15 (program counter)
cpsr (current program status register)
spsr (save program status register) 模式切换时保存前一个模式的cpsr.
r0-r7 : 通用未分组寄存器, 共 8 个
r8-r12 : FIQ模式和其他模式两组, 共10个
r13-r14 : 每种模式各一个, 共2*6 = 12个
spsr : User/System模式没有spsr. 共5个
r15(pc) : 一个
cpsr : 一个
* 从一个模式A切换到另一个模式B执行的动作:
B[spsr] = A[cpsr]
B[cpsr] 位设置 :
如果A处于thumb状态, 进入arm状态
修改Mode[4:0] 位
禁止适当的中断
B[lr] = A[pc]
B[pc] 设置中断向量表的值
* 从模式B返回到模式A
A[cpsr] = B[spsr]
A[pc] = B[lr]
所有指令都能访问 r0-14
大部分指令允许方位 pc
特殊指令允许访问 CPSR 和SPSR
特权模式使用 load/store指定分组(banked out)的用户模式寄存器是可能的.
CPSR和SPSR寄存器的31-28bit分别为: N Z C V
N = ALU结果标记为负数
Z = ALU结果为0
C = ALU操作移位溢出(Carried out, 结果大于32bits)
V = ALU操作溢出(Overflowed, 有符号数操作, 结果大于31bits)
CPSR和SPSR寄存器的8-0bit分别为: I F X T Mode[4:0]
I : 禁止IRQ
F : 禁止FIQ
X : reserved
T : 0 表示 ARM状态, 1 表示处理器处于Thumb状态
Mode[4:0] : 定义处理器模式
ARM采用3级流水线操作:
PC ------- FETCH(预取)
PC-4 ------- DECODE(解码)
PC-8 -------- EXECUTE(执行)
ARM指令的 31-28bit是条件执行, 4位共16种:
0000 = EQ - Z set
0001 = NE - Z clear
0010 = HS/CS - C set(unsigned higher or same)
0011 = LO/CC - C clear (unsigned lower)
0100 = MI - N set (negative)
0101 = PL - N clear(positive or zero)
0110 = VS - V set (overflow)
0111 = VC - V clear(no overflow)
1000 = HI - C set and Z clear (unsigned higher)
1001 = LS - C clear or Z (unsigned lower or same)
1010 = GE - N set and V set, or N clear and V clear ( >=)
1011 = LT - N set and V clear or N clear and V set( > )
1100 = GT - Z clear, and either N set and V set, or N clear and V set(>)
1101 = LE - Z set, or N set and V clear, or N clear and V set (<=)
1110 = AL - always
1111 = Reserved
简单总结: 无符号数比较: H(大于), L(小于), S(等于). 有符号数比较: G(大于), L(小于), E(等于)
一般数据处理操作不影响cpsr中的条件标志,为了更新标志可在指令后加一个“S“. 例如: adds r0, r1, r2
跳转指令:
31-28 27-25 24 23 .... 0
cond 1 0 1 L offset
L : 0 = brank; 1 branch with link(bl)
b<l>{<cond>} label
*跳转指令的的偏移由汇编器计算, 目标地址和跳转指令间距在减8(流水线)
*偏移是26bit的,因为最低2位为0,所以只需写出高24位
*便宜范围为 +/-32Mbytes
注: ARM 4T提供了BX指令切换arm和thumb指令切换
数据处理指令: 算术, 比较, 逻辑, 寄存器间数据移动操作
opcode{<cond>}{S} Rd, Rn, op2
操作数op2有12bits可以使用: 直接使用的话0~4096, 或者使用8bit(0~255) + ROR偶数位(0,2,4....30)
ADD : op1 + op2
ADC : op1 + op2 + carry
SUB : op1 - op2
SBC : op1 - op2 + carry - 1
RSB : op2 - op1
RSC : op2 - op1 + carry - 1
CMP : op1 - op2
CMN : op1 + op2
TST : op1 & op2
TEQ : op1 eor op2
AND : op1 and op2
EOR : op1 eor op2
ORR : op1 or op2
BIC : op1 and (not op2) -- bit clear
MOV : op2
MVN : not op2
op1 总是寄存器Rn
op2 通过移位barrel送到ALU
伪指令ldr可以加载任意32bit数到寄存器
ldr rd, =numeric constant
乘法指令:
mul{<cond>}{S} Rd, Rm, Rs ====> Rd = Rm * Rs
mula{<cond>}{S} Rd, Rm, Rs, Rn ====> Rd = (Rm * Rs) + Rn
mull/mlal : 给出两个寄存器存放结果
umull/umlal : 无符号乘法
smull/smlal : 有符号乘法
Rd 和 Rm不能是同一个寄存器
加载/存储指令:
ldr/str/ldm/stm/swp
ldrb/strb : 单字节操作
ldrh/strh : 半字操作
ldrsb/ldrsh : 加载值并扩展符号位到32bits
例子: pre-index
str r0, [r1, #12] ===> [r1 + 12] := r0
str r0, [r1, #12]! ===> [r1 + 12] := r0, r1 := r1 + 12
str r0, [r1, r2, lsl #2] ===> [r1 + r2<<2] := r0
post-index(不用加”!“) :
str r0, [r1], #12 ====> [r1] := r0, r1 := r1 + 12
ARM可以设置大端或者小端访问数据:
小端 : 低字节存放bit0~7
大端 : 低字节存放bit24~31
多寄存器加载/存储指令:
31-28 27-25 24 23 22 21 20 19-16 15 ............ 0
cond 1 0 1 P U S W L Rn register list
P : Pre/Post indexing bit, 0 = post, add offset after transfer 1= pre, add offset befor transfer
U : Up/Down bit, 0 = Down, subtract offset from base, 1 = Up, add offset to base
S : PSR and force use bit, 0 = don't load PSR or force user mode, Load PSR or force user mode
ldmfd sp!, {r0-r12,pc}^ ===> ! : 表示W为, ^ : 表示S位,传送PC的同时把SPSR写到CPSR中
W : Write-back bit, 0 = no write-back, 1 = write address into base
L : Load/Store bit, 0 = store to memory, 1 = load from memory
register list : 一个bit代表一个寄存器, 1 代表相应寄存器需传送
stmfd/ldmfd : full descending stack
stmfa/ldmfa : full ascending stack
stmed/ldmed : empty descending stack
stmea/ldmea : empty ascending stack
注: arm编译器总是使用满递减栈(stmfd/ldmfd)
数据交换指令: 原子操作指令集
swp{<cond>}{B} Rd, Rm, [Rn]
Rd = [Rn], [Rn] = Rm
软中断指令:
31-28 27 - 24 23 ......................................................... 0
cond 1 1 1 1 Comment filed(ignore by processor)
PSR传送指令:
MRS{<cond>} Rd, <psr> ===> Rd = <psr>
MSR{<cond>} <psr>, Rm ===> <psr> = Rm
MSR{<cond>} <psrf>, Rm ===> <psrf> = Rm
其中 <psr> = CPSR, CPSR_all, SPSR or SPSR_all
<psrf> = CPSR_flg or SPSR_flg
* 用户模式,所有的位都可以读,但是只有标志位可以写
*ARM体系结构支持16个协处理器,可分三类型协处理器指令:
- 协处理器数据处理
- 协处理器数据传送(to/from ARM)
- 协处理器内存传送(load/store to /from memory)
协处理器可以使用硬件/软件(未定义指令异常)来提供.
CDP {<cond>} <cp_num>, <opc_1>, CRd, CRn, CRm, {opc_2}
31-28 27-24 23-20 19-16 15-12 11-8 7-5 4 3-0
cond 1 1 1 0 opc_1 CRn CRd cp_num opc_2 0 CRm
opc_1 : opcode 操作符
opc_2 : opcode 第二个操作符
CRd : 目的寄存器
CRn, CRm : 源寄存器
MCR : 从协处理器取数据到寄存器
MCR : 从寄存器搬运数据到协处理器
<MRC|MCR> {<cond>} <cp_num>, <opc_1>, Rd, CRn, CRm, <opc_2>
31-28 27-24 23-21 20 19-16 15-12 11-8 7-5 4 3-0
cond 1110 opc_1 L CRn Rd cp_num opc_2 1 CRm
L : 0=从协处理器传送到ARM or ...
从内存到协处理器
<LDC|STC>{<cond>} {<L>} <cp_num>, CRd, <address>
<LDC|STC>{<cond>} {<L>} <cp_num>, CRd, [Rn, offset] {!}
<LDC|STC>{<cond>} {<L>} <cp_num>, CRd, <[Rn], offset>
L : 表示long长传送(N=1), 否则short短传送(N=0)