在大学学了2年的单片机,差不多也用了两年的单片机了,但是对其内部细致的工作原来还是有点模糊不清(可能平时的应用可以不涉及到底层工作原理,大部分工作都让编译器和汇编器替我们做了,这也阻碍了我们对底层工作原理的了解啊)。一直在不知其理的状态下开发了这么多年,内心有很多疑问,也有一种被架空的感觉。可能我比较喜欢踏实,所以一直想把内部原理搞明白,这里总结了几点。
首先,我们分析一下单片机(一般处理器)的大致工作原理吧。我们都学过简单的加法电路,计数电路,存储器读写电路和其它具有特定功能的时序电路,这些都是数字电路的时序电路课程中的简单的应用,我们可以把单片机理解为由这些基本时序电路组合而成的较为复杂的数字电路。在正常程序执行流程下,单片机在时钟时序的推动下PC自动计数,控制器根据PC值从程序存储器ROM中读取程序代码(一条指令的存储空间有可能占用一个字节,也有可能占用两个字节,最多占用三个字节),经过程序代码译码后可以得到具体的操作方式(如MOV操作)和操作数(如RO,R1)。
其次,我们理解一下指令--系统。我们可以把单片机的一条指令理解为单片机支持的可执行的一个小流程,当然这个流程是需要单片机内部工艺和硬件的支持的(所以一般单片机指令系统的指令都是有限的,如51单片机支持111条指令)。我们可以理解成一个系列的单片机指令越多(当然这里指的指令都是有意义的指令),单片机运行就会越灵活越高效,当然这对单片机内部处理器硬件要求也越高,这也是制约单片机高效处理的因素之一,不过当下一些高端的单片机系列如ARM系列单片机在指令系统方面已经非常高效。
我们都知道存储指令是需要存储空间的,也就是内部ROM,执行指令需要执行时间,也就是指令周期。对于51单片机中的111条指令最多占用三个字节的存储空间,指令最大的程序执行周期是四个时钟周期(即乘法和除法指令)。这里的存储空间指的是汇编代码汇编成机器码后,机器码占用的存储空间。这里我们或许会思考,一条机器语言必须要包含足够的信息,单片机才能够根据指令运行程序。如MOVACC #0xff 对于这条语句必须占用两个以上字节,因为数据“0xff”占用一个字节,还需要存储操作方式MOV和ACC两个信息。但是如果要对一个地址如0xffff赋一个0xffff的值,那这样理解不是要至少占用5个字节(4个字节分别存储操作地址和操作数,1个字节存储操作方式)。可能大师们一下看出了问题所在,不过当初我就是有这么思考过。结合51指令系统根本没有直接进行将一个16位数赋值给一个16位地址的指令(我承认当时我想多了),这需要由很多指令组合完成操作,那内部存储方式也就是很多指令一起的存储方式了(可能远不止5个字节)。这也是指令系统的微妙之处,他既要考虑存储空间,也要考虑执行周期,同时还要考虑指令功能的全面性。
在51系列单片机中指令中一个周期是可以同时读取两个字节的代码,这相对一个周期读取一个字节的方式来说一定程度上也减少了双字节指令的执行周期。由于读取三字节的指令至少占用两个周期,所以三字节指令执行周期必须是两个周期及以上。
以上是各个指令对应的汇编指令码,机器码和机器执行周期,有助于理解指令的细节。
对于指令系统中不同指令是有不同的寻址方式的,这是单片机内部对数据处理的一套机制,任何其他操作都是建立在这套机制之上的。所以对指令系统的理解有助于对单片机内部的细节工作过程的理解和运用。