参考:<ARM编程与架构> 韦东山
ARM内部寄存器及汇编指令概述
寄存器:
我们说”寄存器”时,需要分辨是哪种:
1.CPU内部的寄存器
2.CPU之外设备自己的寄存器
这是不一样的:
CPU通过各类汇编指令访问内部寄存器
CPU要访问设备的寄存器时,就像访问内存一样,要先知道地址
举例:外部寄存器的地址是0x1000,要读它,使用如下汇编指令:
mov r0,#0x1000 //把外部存器地址值赋给CPU内部寄存器r0
ldr r1,[r0] // 使用r0所表示的地址来读数据,存入CPU内部寄存器r1
一、ARM内部寄存器
无论是cortex-M3/M4,还是cortex-A7,CPU内部都有R0、R1、……R15寄存器;它们可以用来“暂存”数据。
其中R0~R12为通用目的寄存器;
对于R13、R14、R15,还另有用途:
R13:别名SP(Stack Pointer),栈指针
R14:别名LR(Link Register),用来保存返回地址
R15:别名PC(Program Counter),程序计数器,表示当前指令地址,写入新值即可跳转
1.1 M3/M4/A7 CPU内部寄存器
cortex-M3/M4
1)对于cortex-M3/M4来说,比较两个数时,结果保存在哪?
结果就保存在xPSR(Program Status Register)寄存器中
2)对于cortex-M3/M4来说,xPSR实际上对应3个寄存器:
① APSR:Application PSR,应用PSR
② IPSR:Interrupt PSR,中断PSR
③ EPSR:Exectution PSR,执行PSR
这3个寄存器的含义如下图所示
3)这3个寄存器,可以单独访问:
MRS R0, APSR ;读APSR
MRS R0, IPSR ;读IPSR
MSR APSR, R0 ;写APSR
这3个寄存器,也可以一次性访问:
MRS R0, PSR ; 读组合程序状态
MSR PSR, R0 ; 写组合程序状态
所谓组合程序状态,如下图所示:
cortex-A7
A7架构的寄存器介绍及相应的工作模式中的专用寄存器
1)对于A7来说:比较两个数时,结果保存在哪?
结果保存在CPSR(Current Program Status Register)寄存器中
2)组合程序状态,与M3/M4的类似,但是异常编号不同
二、ARM汇编概述
一开始,ARM公司发布两类指令集:
① ARM指令集,这是32位的,每条指令占据32位,高效,但是太占空间
② Thumb指令集,这是16位的,每条指令占据16位,节省空间
要节省空间时用Thumb指令,要效率时用ARM指令。
一个CPU既可以运行Thumb指令,也能运行ARM指令。
怎么区分当前指令是Thumb还是ARM指令呢?
程序状态寄存器中有一位,名为“T”,它等于1时表示当前运行的是Thumb指令。
假设函数A是使用Thumb指令写的,函数B是使用ARM指令写的,怎么调用A/B?
我们可以往PC寄存器里写入函数A或B的地址,就可以调用A或B,
但是怎么让CPU在执行A函数是进入Thumb状态,在执行B函数时进入ARM状态?
做个手脚:
调用函数A时,让PC寄存器的BIT0等于1,即:PC=函数A地址+(1<<0);
调用函数B时,让PC寄存器的BIT0等于0:,即:PC=函数B地址
麻烦吧?麻烦!
引入Thumb2指令集,它支持16位指令、32位指令混合编程。
有那么多指令集:ARM、Thumb、Thumb2,
不好记啊!
不用区分它们,不用担心,
ARM公司推出了: Unified Assembly Language
UAL,统一汇编语言,你不需要去区分这些指令集
2.1 日常工作中常用的几条汇编指令
MOV
LDR/STR
LDM/STM
AND/OR
ADD/SUB
B/BL
DCD
ADR/LDR
CMP
注:写不出很复杂的汇编程序?没必要写很复杂的,设置栈后就用C语言来写函数
2.2 汇编指令格式
以“数据处理”指令为例,UAL汇编格式为:
Operation表示各类汇编指令,比如ADD、MOV;
cond表示conditon,即该指令执行的条件;
S表示该指令执行后,会去修改程序状态寄存器;
Rd为目的寄存器,用来存储运算的结果;
Rn、Operand2是两个源操作数
参考:参考《DEN0013D_cortex_a_series_PG.pdf》P70、《ARM Cortex-M3与Cortex-M4权威指南.pdf》第5章