1、ARM寄存器
概念:寄存器是处理器内部的存储器,没有地址
作用:一般用于暂时存储参与运算的数据和运算结果
分类:通用寄存器、专用寄存器、状态寄存器
注意:有标签(带三角光标)的是独有的寄存器
总结:
ARM7,9,11 有37个寄存器
30 个通用寄存器
1 个用作PC( program counter)
1个用作CPSR(current program status register) 当前程序状态的寄存器
5个用作SPSR(saved program status registers) 保存程序状态的寄存器
Cortex-A多出3个寄存器,即有40个寄存器
Monitor 模式r13_mon , r14_mon, spsr_mon
R0-R15, CPSR,SPSR 这些寄存器是由ARM公司提供,每个寄存器都是32位的。
这些寄存器没有地址,只有一个唯一的编号,通过这些编号,就可以访问对应的地址空间。
R0-R15,cpsr,spsr就是对应的编号,每个编号都对应的32位二进制
专用寄存器
R13(SP,Stack Pointer)
栈指针,用于存储当前模式下的栈顶地址
R14(LR,Link Register)
链接寄存器:函数调用时,保存返回地址
(保存调用函对应指令的下一条指令地址,返回的时候把LR值给PC,可以继续执行接下来的代码)
一般有以下两种用途:
> 执行跳转指令(BL/BLX)时,LR会自动保存跳转指令下一条指令的地址
程序需要返回时将LR的值赋值到PC即可实现
> 产生异常时,对应异常模式下的LR会自动保存被异常打断的指令的下
一条指令的地址,异常处理结束后将LR的值赋值给PC即可实现程序返回
R15(PC,Program Counter)
程序计数器:用于存储当前取址指令的地址(下一条指令)
CPU从内存中一条一条的拿指令(取指)
CPSR寄存器
CPSR(Current Program Status Register),当前程序状态寄存器
存储当前程序运行状态
NZCV这几位叫条件位,后边八位叫控制位(C表示)
CPSR寄存器分为四个域
[31:24]为条件域用F表示
[23:16]为状态域用S表示
[15:8]为预留域用X表示
[7:0]为控制域用C表示
Bit[4:0]
[10000]User [10001]FIQ [10010]IRQ [10011]SVC
[10111]Abort [11011]Undef [11111]System [10110]Monitor
Bit[5]
[0]ARM状态 [1]Thumb状态
Bit[6]
[0]开启FIQ [1]禁止FIQ
Bit[7]
[0]开启IRQ [1]禁止IRQ
Bit[28]
> 当运算器中进行加法运算且产生符号位进位时该位自动置1,否则为0
> 当运算器中进行减法运算且产生符号位借位时该位自动置0,否则为1
Bit[29]
> 当运算器中进行加法运算且产生进位时该位自动置1,否则为0
> 当运算器中进行减法运算且产生借位时该位自动置0,否则为1
Bit[30]
当运算器中产生了0的结果该位自动置1,否则为0
Bit[31]
当运算器中产生了负数的结果该位自动置1,否则为0
SPSR寄存器
SPSR:保存程序状态的寄存器( saved program status register)
用于保存CPSR(通用寄存器,在切换模式的时候用)
2、ARM的工作模式
ARM有8种工作模式
- User :非特权模式,一般在执行上层的应用程序时ARM处于该模式大部分任务执行在这种模式 (运行程序在这个模式)
- FIQ :当一个高优先级(fast) 中断产生时将会进入这种模式
- IRQ:当一个低优先级(normal) 中断产生时将会进入这种模式
FIQ和IRQ打断当前正在做的事去做其他的事情,做了再回来继续做自己的事情。鼠标键盘等都是这样实现的。(Linux内核会有中断,驱动写中断驱动代码)
- SVC(Supervisor):当复位或软中断指令执行时将会进入这种模式
(任务的切换会切入这个模式,权限最高的模式,刚启动的时候在这个模式下,权限高,可以做一些核心的操作。进行系统调用的时候会切换这个模式。)
- Abort :当指令产生存取异常时ARM将会进入这种模式
- Undef :当执行未定义指令时ARM会进入这种模式
- System :使用和User模式相同寄存器集的特权模式
保证不同任务每次调用同一个函数都是从头开始。
- Monitor : 是为了安全而扩展出的用于执行安全监控代码的模式。也是一种特权模式(Cortex-A特有模式)
工作模式的理解
不同的模式拥有不同的权限
不同的模式执行的代码不同
不同的模式拥有不同的功能
特定的模式拥有特定的权限,执行特定的代码,完成特定的功能
CPU运行原理
根据下载的程序运行,程序就是指令的有序集合
3、指令的解析
一条指令(机器码)的执行通常分为三个阶段:
1)取指:控制器将PC寄存器中的值发送给内存,内存将对应地址中的指令(机器码)传送回CPU的指令寄存器IR中
2)译码:指令译码器对IR中的指令进行识别,将指令(机器码)解析(翻译)成具体的运算操作(+/-/*...)
3)执行:控制器控制运算器中对应的运算单元进行运算,运算结果写入寄存器
注意:PC每取地址一次,自加一次。PC的值自动增加使PC指向内存中的下一条指令
思考:
- 运算器不同,处理指令不同。不同的处理器上如何运行同一个c语言程序?
- 假设指令集有乘法指令,结果并没有乘法运算器,怎么办?
可以转换为加法指令
寻址空间
一个处理器能够访问(读写)的存储空间是有限的,我们把这个空间称为地址空间(寻址空间)。通常情况下地址空间的大小2的N次方
32位操作系统,寻址为32位。0x00000000 ~ 0xFFFFFFFF寻址空间位2^32,4G。
指令流水线
指令的执行是按照流水线
取指--》取指器 根据PC值取指令
译码--》译码器
执行--》执行器
以上三个器件,都是单周期的器件,三个器件的工作是独立
指令1 指令2 指令3 指令4 指令5
1 取指
2 译码 取指
3 执行 译码 取指
4 执行 译码 取指
5 执行 译码 取指
6 执行 译码
7 执行
PC永远指向当前取指指令的地址,一旦取到指令,pc后移4byte,保存下一条指令地址。
指令流水线机制的引入确实能够 大大的提升指令执行的速度 ,但在实际执行程序的过程中很多情况下流水线时是无法形成的,比如芯片刚上电的前两个周期、执行跳转指令后的两个周期等。
所以指令流水线的引入以及优化 只能使平均指令周期不断的接近1而不可能真正的达到1, 且流水线级数越多芯片设计的复杂,程度就越高,芯片的功耗就越高。
4、ARM的异常处理
1)异常
概念 :处理器在正常执行过程中可能遇到一些不正常的事件发生,这时处理器就要将当前程序暂停下来转而去执行这个异常事件,异常事件处理完之后返回被异常打断的地方继续执行。
2)ARM异常源
概念:导致异常产生的事件称为异常源
ARM异常源
FIQ 快速中断请求引脚有效
IRQ 外部中断请求引脚有效
Reset 复位电平有效
Software Interrupt 执行swi指令
Data Abort 数据终止
Prefetch Abort 指令预取终止
Undefined Instruction 遇到不能处理的指令
3)ARM异常模式
在ARM的基本工作模式中有5个属于异常模式,ARM遇到异常后会切换成对应的异常模式
4)异常处理机制
不同的处理器对异常的处理的流程大体相似,但是不同的处理器在具体实现的机制上有所不同;比如处理器遇到哪些事件认为是异常事件遇到异常事件之后处理器有哪些动作、处理器如何跳转到异常处理程序如何处理异常、处理完异常之后又如何返回到被打断的程序继续执行等我们将这些细节的实现称为处理器的异常处理机制。
5)异常向量表
- 异常向量表的本质是内存中的一段代码
- 表中为每个异常源分配了四个字节的存储空间(32位处理器)
- 遇到异常后处理器自动将PC修改为对应的地址
- 因为异常向量表空间有限一般我们不会在这里写异常处理程序,而是在对应的位置写一条跳转指令使其跳转到指定的异常处理程序的入口
注:ARM的异常向量表的基地址默认在0x00地址但可以通过配置协处理器来修改其地址
6)ARM异常响应(四大步、三小步)
ARM产生异常后的动作(自动完成)
1、拷贝CPSR中的内容到对应的异常模式下的SPSR
2、修改CPSR的值
2.1修改中断禁止位禁止相应的中断
2.1修改模式位进入相应的异常模式
2.3修改状态位进入ARM状态
3、保存返回地址到对应模式下的LR中
4、设置PC为相应的异常向量
7)异常返回
ARM异常返回动作(自己编写)
1、将SPSR的值复制给CPSR-->恢复为跳转之前的模式
- 将LR的值复制给PC-->返回跳转之前程序执行的地方
8)IRQ异常举例
IRQ异常是指当CPU接收到一个中断请求时,会暂停当前正在执行的程序,转而去执行与中断请求相关的处理程序。
例子:键盘中断
当用户按下键盘上的某个键时,键盘会向CPU发送一个中断请求,CPU会暂停当前正在执行的程序,转而去执行与键盘中断相关的处理程序,以响应用户的操作。在处理完中断请求后,CPU会返回到原来的程序继续执行。
9)异常优先级
Reset(重置)
处理器上电或者复位时发生的异常
Data Abort(数据中止)
数据访问错误时发生的异常,一般是与Memory 误操作有关,如对0地址写操作,或对一些Memory 越界操作。或者指令不支持
FIQ (快速中断)、IRQ (普通中断)
FIQ 具有更高的优先级,即当 FIQ 发生时,CPU 会在当前指令执行完成后立即响应 FIQ 中断,而忽略其他 IRQ 中断。这使得 FIQ 更适合处理紧急、实时性要求较高的中断。
Prefetch Abort(指令预取错误时发生的异常)
当CPU在执行指令时,发现指令缓存中没有下一条指令时,就会发生预取指中止异常。这种异常通常是由于程序中的错误或者硬件故障引起的。由于预取指中止异常的信息不够详细,因此很难定位和修复问题。
Software Interrupt(软件中断)
软件中断是一种由应用程序发起的中断,用于请求操作系统提供服务或执行某些操作。当应用程序需要访问受保护的资源或请求操作系统提供服务时,它会发出一个软件中断信号,这个信号会被CPU接收并暂时将控制切换到一个中断处理程序,内核中被中断挂起的进程将在中断被接受后恢复。软件中断可以被看作是同步事件,因为它是由应用程序主动发起的,而不是由外部设备触发的。
Undefined instruction(执行了未定义指令时发生的异常)
Undefined instruction异常是ARM处理器中的一种异常类型,当CPU遇到不认识的指令时,就会触发该异常。在异常处理函数中,可以对该异常进行处理,例如打印debug信息或者进行其他操作。