笔者在嵌入式领域深耕6年,对嵌入式项目构建,BLDC电机控制,产品上位机开发以及产品量产和产品售后维护有多年工作经验。经验分享,从0到1, 让我带你从实际工作的角度走进嵌入式成长之路。
原创不易,欢迎大家关注我的微信公众号:嵌入式工程师成长之路 或 扫下面二维码
所有文章总目录:【电子工程师 qt工程师】
原创视频总目录:【电子工程师 qt工程师】
1.汇编语言的本质
CPU的本质就是将很多模块化的组合逻辑电路组合(数字电子技术,用二极管、三极管、与非门等基础模块搭建的数字电路)在一起;每一个模块的组合逻辑电路都实现了相应的功能。
例如,减法逻辑组合电路实现了减法的功能,左移电路实现了左移的功能。每一个功能都是一个接口,我们使用减法只要调用对应的功能接口就可以了。这些接口就是机器码(机器码是0101的二进制,其本质就是组合逻辑电路的开关,和我们房间里灯的开关是一样的)。而汇编指令仅仅是这些机器码/二进制的助记符。也就是一条汇编指令一定有一条和他对应的机器码。
因为不同架构的CPU都是不同公司设计的,所以他们内部的组合逻辑电路的实现方式不同,也就是每个功能其对应的机器码不同,机器码不同功也就是汇编指令不同。所以才说,不同架构的CPU有不同的汇编指令。用arm汇编指令写的程序不能运行在intel架构的CPU中。
总结一句话,可以将汇编语言看是应用开发中的API接口,这个API接口的具体实现就是实现这个汇编指令的那一堆组合逻辑电路。汇编指令和机器码是一一对应的关系。在一些需要执行效率的场所,例如操作系统内核和中断处理一般才会用汇编语言来写,通常情况一般都是使用C语言来写。
2.程序的执行
一条指令的执行分为三个过程,即CPU的三级流水线;当CPU要执行内存中的一条指令时,会经过以下三步:读取指令—>译码(CPU理解该指令)—>执行(理解完之后就是执行)。
注:
arm采用的就是这种三级流水线技术来执行一句代码的。
3.程序可移植性的本质
汇编语言没有移植性,因为每种架构的CPU都有自己的机器码指令集。
C语言有一定的移植性,因为C语言要经过汇编器编译为汇编代码之后再给CPU执行的,同一个C语言程序,只有通过对应于这个架构的CPU的汇编器编译之后才能运行到对应架构CPU中去。
譬如有arm汇编器和intel汇编器,C语言没有移植性,但是针对不同架构的CPU有对应的汇编器,所以使得C语言有了可移植性;就像java语言一样,java本身没有移植性,但是我们开发出了针对不同平台的JVM,同一个java程序要先运行在对应平台的JVM中,然后才能运行在具体的操作系统中,这也就使得java有了可移植性。
4.复杂指令集(CISC)CPU和精简指令集(RISC)CPU的区别
复杂和精简体现在CPU的指令的数量;复杂指令集就是这种CPU有非常多的指令,精简指令集的CPU的指令相对比较少。
CISC架构的CPU指令集中的指令数量很多,它的设计理念就是使用最少的指令数来完成一个操作,譬如一个乘加(先乘后加)指令,在CISC架构的CPU中可能直接存在一条这样的乘加指令来完成乘加操作;但是在RISC架构中,可能只提供乘法指令和加法指令,然后乘加操作要靠这两个指令结合来完成。
也就是说在CISC架构的CPU中一个操作可能就直接对应一条CPU指令,这样就是导致了CPU本身的设计变得十分复杂,因为一条指令的本质就是在CPU内部的一堆数字电路,也正是因为数字电路一多就导致CPU的功耗很大。intel一般都是CISC架构的CPU,这种CPU一般用在高性能的服务器中。
精简指令集架构就是CPU的指令的条数更少了,一般的Intel的CPU有300条指令,而RISC架构的CPU(譬如ARM)只有大概30条指令。RISC的设计理念就是通过提供的最基本30多条指令来完成各种复杂操作。RISC架构的CPU设计简单,但是相对来讲它的程序写起来更为复杂。同时它也是低功耗的。典型的就是ARM结构的CPU。
5.IO与内存统一编址和IO与内存独立编址的区别
CPU能访问的内存大小和CPU自身的地址总线的位数有关,arm CPU的地址总线是32位的,也就是最多只能访问4G的内存空间。
IO可以理解为就是CPU的引脚,CPU外设和CPU相连就是通过IO引脚的,所以现在也直接将IO就理解为外设,我们操作外设,本质就是去操作这个外设的寄存器,arm的每一个寄存器都是32位的,那怎样访问这个寄存器呢?arm采用的是IO与内存统一编址,也就是将这个外设的寄存器当作内存,所有的外设都是这样的;譬如s5pv210实际的内存只有1.5G,其他的分给了外设的寄存器了。
IO与内存统一编址的实质就是访问IO外设的方式和访问内存的方式是一样的。这种方式访问这些特殊功能寄存器的效率比较高,但也要占用一定的内存的地址。
独立编址就是我们操作外设的寄存器需要CPU对应的指令,譬如我们要读串口的寄存器,就可能需要专门的读串口指令来完成,而不是通过地址。这种方式来访问,可以不用占用内存地址,但效率比较低。
6.哈佛架构和冯诺依曼架构的区别
– 冯诺依曼结构
程序就是对数据的加工器。所以在本质上,程序段一般只需要用来读,而不能写;而数据段是需要被读和被写的。
注意,在存储器中,程序段和数据段都是二进制的。所以冯诺依曼就提出,程序也是一种数据,所以就有了冯诺依曼结构。也就是将程序段和数据段放在一起(具体在CPU内部怎么处理的可以不用管)。在这种架构中,CPU处理对二进制的处理比较方便,因为不管是数据还是程序直接读进来就行了。
但是,正是因为程序段和数据段放在了一起(交织在一起),所以程序在运行的时候就可能会将程序段中的程序误以为是数据,也就是不小心将程序段给改了,这样就有可能导致程序奔溃。所以这种架构的CPU一般用在桌面电脑中,因为即使出现这种错误,直接重启就好了,并不会造成致命的伤害。
– 哈佛结构
哈佛结构的思路就是将数据和程序分开存放,当然在内存中,他们还是在一起的,一块内存中,可能这一部分是用来放数据的,这一部分是用来放程序的,这种划分通过操作系统来完成。
所以哈弗结的CPU比较安全,因为不会出现自己踩到自己的错误,所以这种CPU一般用在嵌入式领域,因为嵌入式领域一般都是要求比较安全。
7.通用寄存器和特殊功能寄存器的区别
通用寄存器是在CPU内部的,譬如R0、R1等,通用寄存器里面存放什么数据由我们自己决定;特殊功能寄存器属于SOC外设的一部分,相当于专门用来操作该外设的接口。
8.ARM体系架构总结
- arm是RISC结构的。
- arm是低功耗的。
- arm的结构非常适合单片机、嵌入式,尤其是物联网领域;服务器等高性能领域目前主导的还是intel。
- 大部分arm(M3\\M4\\M0\\ARM9\\ARM11\\A8\\A9等)都是32位架构的。
- 内存和特殊功能寄存器都是通过地址总线直线访问的。也就是IO与内存统一编址。
- arm是哈佛架构的。
注:
由于ARM架构的CPU(除ARM7之外)都是RISC架构的,所以ARM都是内存与IO统一编址的,这样就导致ARM实际用作内存的地址少于4G,也就是用来放数据的程序的地址是少于4G的,因为有一部分地址已经留给了IO外设对应的寄存器。