1.处理器内部数据传输指令
使用处理器最多的操作就是在处理器内部来回传递数据,常见操作:
- 将数据从一个寄存器传递到另一个寄存器;
- 将数据从一个寄存器传递到特殊寄存器(如CPSR、SPSR);
- 将立即数传递到寄存器;
(1)mov指令
MOV R0, R1 @将寄存器R1中的数据传递给R0,即R0=R1
MOV R0, #0X12 @将立即数0x12传递给R0,即R0=0X12
(2)mrs指令(读特殊寄存器)
MRS R0, CPSR @将特殊寄存器CPSR中的数据传递到通用寄存器R0,即R0=CPSR
(3) msr指令(写特殊寄存器)
MSR CPSR, R0 @将通用寄存器R0的数据复制到特殊寄存器CPSR,即CPSR=R0
2.存储器访问指令
ARM不能直接访问存储器
指令 | 描述 |
---|---|
LDR Rd,[Rn,#offset] | 从存储器Rn+offset地址读取数据存放到Rd |
STR Rd,[Rn,#offset] | 将Rd中的数据写入到存储器中Rn+offset地址 |
(1)LDR指令(读)
LDR R0, =0X0209C004 @将地址0X0209C004加载到R0中,即R0=0X0209C004(立即数用=而不是#)
LDR R1, [R0] @读取地址0X0209C004中的数据到R1中
(2)STR指令(写)
LDR R0, =0X0209C004 @将寄存器地址0X0209C004加载到R0中,即R0=0X0209C004
LDR R1, =0X20000002 @R1保存要写入到存储器的值,即R1=0X20000002
STR R1, [R0] @将R1中的值写入到R0中所保存的地址中
3.压栈和出栈指令
处理器的栈是向下增长的
PUSH {R0~R3,R12} @将R12、R3、R2、R1、R0依次压栈
PUSH {LR} @将LR压栈
POP {LR} @先恢复LR
POP {R0~R3, R12} @依次恢复R0~R3,R12
等价操作
STMFD SP!,{R0~R3,R12}
STMFD SP!,{LR}
LDMFD SP!,{LR}
LDMFD SP!,{R0~R3,R12}
4.跳转指令
(1)B指令
B指令会将PC寄存器的值设置为跳转目标地址,一旦执行,ARM处理器会立马跳转到指定目标地址
_start:
LDR SP,0X80200000 @设置栈指针
B main @跳转到main函数
(2)BL指令
相比B指令,会在跳转之前在寄存器LR(R14)中保存当前PC值,所以可以将LR值重新加载到PC中跳回之前位置继续运行
PUSH {R0,R1} @R0、R1入栈
CPS #0X13 @进去SVC模式、允许其他中断再次进去
BL system_irqhandler @加载C语言中断处理函数到R2寄存器中
CPS #0X12 @进去IRQ模式
POP {R0,R1} @R0、R1出栈
STR R0,{R1,#0X10} @中断执行完成,写EOIR
5.算数运算指令
指令 | 计算公式 |
---|---|
ADD Rd,Rm,Rn | Rd=Rm+Rn |
Add Rd,Rm,#immed | Rd=Rm+#immed |
ADC Rd,Rm,Rn | Rd=Rm+Rn+进位 |
ADC Rd,Rm,#immed | Rd=Rm+#immed+进位 |
SUB Rd,Rm,Rn | Rd=Rm-Rn |
SUB Rd,Rm,#immed | Rd=Rm-#immed |
SBC Rd,Rm,Rn | Rd=Rm-Rn-借位 |
SBC Rd,Rm,#immed | Rd=Rm-#immed-借位 |
6.逻辑运算指令
指令 | 计算公式 |
---|---|
AND Rd, Rn | Rd = Rd &Rn |
AND Rd, Rn, #immed | Rd = Rn &#immed |
AND Rd, Rn, Rm | Rd = Rn & Rm |
ORR Rd, Rn | Rd = Rd |
ORR Rd, Rn, #immed | Rd = Rn |
ORR Rd, Rn, Rm | Rd = Rn |
BIC Rd, Rn | Rd = Rd & (~Rn) |
BIC Rd, Rn, #immed | Rd = Rn & (~#immed) |
BIC Rd, Rn , Rm | Rd = Rn & (~Rm) |
EOR Rd, Rn | Rd = Rd ^ Rn |
EOR Rd, Rn, #immed | Rd = Rn ^ #immed |
EOR Rd, Rn, Rm | Rd = Rn ^ Rm |