CPU工作原理
CPU与内存中的内容:
内存中存放了指令,每一个指令存放的地址不一样,所需的内存空间也不一样。
运算器能够进行算数运算和逻辑运算,这些运算在CPU中都是以运算电路的形式存在,一个运算功能对应一种运算电路。程序中有哪种运算,CPU的运算器中就要有相应的运算电路与之对应。
控制器负责代码运行的过程,有指令计数器PC、指令寄存器IR、指令译码器。
- PC中存放的是想要执行的指令的地址
- IR中存放从内存中读取到的指令
- 指令译码器负责将指令翻译为对应的操作并发给运算器。
CPU如何执行程序:
CPU是串行工作方式,即同一时刻只能进行一种运算。执行过程有取指、译码、执行这三步。
- 取指
取指就是CPU从内存中取出所需要执行的指令。
CPU将PC中存放的地址数据通过地址总线告诉内存,即:告诉内存,我想要执行哪里的指令。内存接收到PC的地址数据后,定位到指定的地址,并将地址的数据通过数据总线发给CPU,这个数据将存放在CPU的指令寄存器IR中。
- 译码
译码就是将IR中的数据翻译为具体的运算含义。
CPU将IR中的数据发送给指令译码器,通过译码之后CPU获取到该指令的具体含义。
- 执行
执行就是将翻译的指令进行真正的运算,得出相应的结果。
译码器翻译之后,将会把这个译码后的内容给指定的运算电路。比如译码出来是乘法运算,那么数据就会发给乘法运算电路,而不是发给加法运算电路。运算电路运算之后将会把结果放在一个寄存器中。
执行之后,PC的值自动偏移指令所需空间的大小值,以便于下一条指令的执行。
ARM概述
1、ARM产品
ARM、CPU、SOC的关系:
ARM内核不是完整的CPU,而是CPU芯片中的核心部分,它需要与其他组件(如缓存、输入/输出接口等)一起集成到一个芯片上,才能构成一个完整的CPU。
SOC就是系统级芯片,也叫片上系统,它指的是将CPU和该产品所需的外设集成在一个芯片中的技术。
ARM系列产品有哪些:
ARM产品的命名发展为:ARM7->ARM9->ARM11->ARM-Cortex。其中Cortex分为A、R、M,不同的类型应用场景也不同。
- ARM-Cortex A系列:针对开放式操作系统的高性能处理器,应用于智能手机、数字电视、智能本等高端运用
- ARM-Cortex R系列:针对实时系统、满足实时性的控制需求,应于汽车制动系统、动力系统等
- ARM-Cortex M系列:为单片机驱动的系统提供了低成本优化方案,应用于传统的微控制器市场、智能传感器、汽车周边等
2、ARM指令集
2.1 指令集相关概念
什么是指令:
指令就是CPU能够认识的代码,一个CPU能够执行哪些指令,这与CPU的硬件设计相关。指令与CPU的运算器中的运算电路要一一对应,只有这样CPU在译码指令之后才能真正将指令发给运算器去执行。
指令在内存中是以机器码(二进制)的方式存在的,每一条指令都对应一条汇编语言。注意:高级语言C语言与指令并不是一一对应的关系,比如CPU在只有加法但没有乘法的运算电路时,要执行3*3,C语言中可以直接写入3*3,这时编译器会将3*3编译为3+3+3这就对应3条汇编语句,也就是对应3条指令,即:CPU会执行3遍加运算来实现C语言中的3*3语句。
程序就是指令的有序集合。
什么是指令集:
指令集就是处理器能够识别的指令的集合,是处理器对开发者提供的接口,即:作为开发者,并不关心CPU中加法电路是如何实现的,只关心哪一条汇编对应加法运算,调用该汇编即可控制加法电路进行工作。
不同架构的处理器指令集也不同,因为每个CPU的运算器中的运算电路可以不同,这就导致CPU能够识别的指令不同,从而指令集不同。
什么是精简指令集RISC:
ARM属于精简指令集处理器。处理器的内核分为两类,一种是精简指令集RISC,一种是复杂指令集CISC,其中ARM是精简指令集内核中应用最广的一种处理器。
RISC就是只保留常用的简单指令,如加减乘除。因此与之对应的硬件运算电路也相应减少,具有硬件结构简单的特点。对于不常用的复杂指令,将通过常用的指令组合实现,这使得性能有所降低。RISC的指令长度是固定的,且多为单周期指令。综上:RISC适用于功耗小、体积小、价格低的需求场景,这就是嵌入式领域。
CISC就是保留了全部的指令,因此对应的硬件运算电路也比较庞大。因为有足够多的针对性的运算电路,所有性能也比较高。CISC的指令长度和周期都不固定。综上:CISC适用于高性能的场景,多于PC及服务器领域。
2.2 ARM指令集
大多数的ARM处理器都支持ARM指令集和Thumb指令集。
ARM指令集:
ARM指令集的指令(机器码)占用32bit空间。ARM指令集的空间大、格式统一、译码简单。
使用ARM指令集时,PC值每次自增4(32bit)。PC存放的是地址,一个地址对应的空间为一字节,因此偏移4,就是32bit。
Thumb指令集:
Thumb指令集的指令(机器码)占用16bit空间。Thumb指令集的代码密度高、节省空间。
使用Thumb指令集时,PC值每次自增2(16bit)。
一般不使用Thumb指令集。
3、编译原理
机器码:
不同的处理器对应的机器码不同,比如上图所示,x86执行加指令对应的机器码是0101,ARM执行加指令对应的机器码是1100,这种情况代表机器码在不同平台上不具有可移植性。
汇编语言:
因为机器码是二进制形式,所以对于人来讲识别比较困难,因此出现了汇编语言。汇编语言实际上就是用一些人能看得懂的符号去表示机器码,它与机器码是一一对应的关系。因此不同的处理器对应的汇编语言不同,汇编语言在不同平台上不具有可移植性。
编译工具与高级语言:
高级语言C语言能够实现移植性的问题,这时因为编译器将C语言编译为了不同的汇编语言,从而将汇编语言汇编为相应的机器码。即:不同的平台不需要不同类型的C语言代码,但是需要不同类型的编译器。
4、ARM存储模型
ARM存储模型指的是ARM如何存储程序和指令。
4.1 数据存储
什么是32位架构:
ARM采用32位架构,代表ARM处理器单次处理数据的能力。32位架构代表CPU可以一次性运算32位的数据。
数据类型:
Byte -- 8位、Halfword -- 16位、Word -- 32位
C语言的char对应Byte,short对应Halfword,int对应Word。ARM并不能处理浮点型数据float、double,对于这些数据ARM一种方法是用已有的运算进行组合,从而实现浮点运算;另一种方法是使用协处理器,让其他处理器去处理浮点运算。
数据存储:
数据本身是多少字节,在内存存储时就应该以多少字节对齐。
Word型数据在内存的起始地址必须为4的整数倍,比如起始地址0、4、8,但2、6不行。
Halfword型数据在内存的起始地址必须为2的整数倍,比如起始地址0、2、4,但1、3不行。
这就是C语言结构体中的数据需要对齐的原因。
字节序:
字节序指的是对于一个数据有多个字节时,数据在内存中的排序方式,字节序分为大端字节序和小端字节序。大端字节序就是低地址放高位,小端字节序就是低地址放低位。
ARM一般使用的是小端字节序。
4.2 指令存储
ARM支持ARM指令集和Thumb指令集,这两种指令集对应ARM状态和Thumb状态。
指令本身是多少字节,在内存存储时就应该以多少字节对齐。
ARM状态:
当ARM处理器处于ARM状态时,所有指令在内存的起始地址必须为4的倍数,这是因为ARM指令集规定一条指令为32位。
当数据为4的整数倍时,转为二进制后最低两位一定为0。CPU中的PC指向要取出的指令的首地址,因此PC值的最低两位也一定为0。因此PC值由[31:2]决定,[1:0]未定义。
[1:0]为未定义的含义是该两位的值会被强制设置为0。因为PC值可以由开发者自行更改,假如在ARM状态非法设置了PC=3(正确情况应该是4的整数倍),这时3转为二进制为...0000 0011(共32位),低两位的11会被强制转为00,最终CPU获取到的PC值是PC = 0。
Thumb状态:
当ARM处理器处于Thumb状态时,所有指令在内存的起始地址必须为2的倍数,这是因为Thumb指令集规定一条指令为16位。
当数据为2的整数倍时,转为二进制后最低一位一定为0。CPU中的PC指向要取出的指令的首地址,因此PC值的最低一位也一定为0。因此PC值由[31:1]决定,[0]未定义。
[0]为未定义的含义是该位的值会被强制设置为0。具体含义与ARM状态类似。
5、ARM工作模式
ARM的工作模式:
ARM有8种工作模式,分别是User、FIQ、IRQ、SVC、Abort、Undef、System、Monitor。
- User:用户模式,也叫非特权模式。当执行上层应用程序时,ARM处于该种模式。User模式下的权限是最低的。
- FIQ:快中断模式,当一个高优先级的中断产生时,ARM进入该模式。
- IRQ:外部中断模式,当一个低优先级的中断产生时,ARM进入该模式。
- SVC:管理模式,当复位或软中断时,ARM进入该模式。
- Abort:终止模式,当CPU存取数据时出现异常时(如:野指针),ARM进入该模式。
- Undef:指令未定义模式,当CPU执行了不认识的指令时,ARM进入该模式。
- System:系统模式,使用和User模式一样,但比User的权限高。
- Monitor:监控模式,为了安全而扩展出的用于执行安全监控代码的模式
模式分类:
1、特权/非特权
User为非特权模式,权限最低。除User外的模式都是特权模式。
2、正常/异常
FIQ、IRQ、SVC、Abort、Undef属于异常模式,User、System、Monitor属于正常模式。
异常模式就是CPU正常执行时候被打断了或者不正常执行的状态。