大家都学过,所谓的8086是冯诺依曼结构的(也叫做普林斯顿结构),51等单片机是哈佛结构,我们的PIC单片机是增强型的哈佛结构。那么,这三种结构之间究竟有什么区别吗?对于我们编程序的时候,有什么影响吗?这篇文章主要来讨论这个问题。 一、问题的引出最近在读linux的内核,遇到这么一个问题:对于PC机而言,操作系统在最开始进行环境初始化的时候,首先执行BIOS程序(有点类似于bootloader),执行完了之后,程序需要从外设(软盘或者硬盘)中,将代码读到RAM区域,进而在RAM中运行相应的代码。这就产生了一个问题:在我们的PIC单片机(包括51)中,程序不都是存在flash里面的么?CPU都是直接从FLASH中直接读取程序,没有听说要把程序从FLASH中读取到RAM中,再读取到CPU中运行吧?于是,我就产生了一个疑问:程序,到底是在RAM中运行的,还是在FLASH中运行的呢?于是就找到了这个网页:http://www.zdh1909.com/html/dgjs/5902.html总结一下这个文章说的内容,意思就是:冯诺依曼结构的,是在RAM中将指令读取到CPU中;哈佛结构的是从FLASH中读取。那么,究竟什么是冯诺依曼结构,什么是哈佛结构?区别到底是什么? 二、冯诺依曼结构和哈佛结构可以参考这篇文章:http://blog.sina.com.cn/s/blog_4c60c6360100f9bs.html冯·诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度相同,如英特尔公司的8086中央处理器的程序指令和数据都是16位宽。哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。中央处理器首先到程序指令存储器中读取程序指令内容,解码后得到数据地址,再到相应的数据存储器中读取数据,并进行下一步的操作(通常是执行)。程序指令存储和数据存储分开,可以使指令和数据有不同的数据宽度,如Microchip公司的PIC16芯片的程序指令是14位宽度,而数据是8位宽度。这段话什么意思呢?回想一下我们学过的8086的编程。当我们需要执行JMP跳转指令的时候,我们都是这么做的: mov ax,[bx] mov ds,ax jmp go sub ds,dsgo: mov ax,cs mov ds,ax 第一句话,将bx所指向的内存单元的内容送到AX中。注意看jmp这句话。当执行完mov ds,ax这句话的时候,要执行jmp go这条指令,然后程序会跳转到mov ax,cs这句话,继续执行。那么,mov ax,cs这句话是存在哪里的呢?没错,跳转到的位置,也是在内存中的某个位置;换句话说,指令是存在内存里面的,而且和[bx]所指的内存区域,是同一块内存的不同区域!这就是冯诺依曼结构的精髓!因此,冯诺依曼指出:程序只是一种(特殊)的数据,它可以像数据一样被处理,因此可以和数据一起被存储在同一个存储器中——这就是著名的冯诺依曼原理。 但是,哈佛结构认为,程序和数据应该分开。因此,就如同我们的PIC单片机一样,程序是存在flash中的,而数据是放在ram中的。每个存储模块都不允许指令和数据并存;使用独立的两条总线,分别作为CPU与每个存储器之间的专用通信路径,而这两条总线之间毫无关联。因此,上面那个汇编程序,如果是放在哈佛结构下的,那么jmp go这句话,还是在flash中存储的;而[bx]指向的数据则是在RAM中的。 这里插一句,增强型的哈佛结构和普通的哈佛结构区别在于:(来自于http://www.pic24micro.com/harvard_vs_von_neumann.html)The Modified Harvard architecture is very much like the Harvard architecture but provides a pathway between the instruction memory and the CPU that allows words from the
instruction memory to be treated as read-only data. Constant data, particularly text strings or images can be accessed without first having to be copied into data memory, thus preserving more data memory for read/write variables. Special machine language instructions
are provided to read data from the instruction memory. Since the program and data memories can have different bit depths, this constant data must be accessed in a way that preserves the alignment of information in both spaces.换句话说,改进的哈佛结构允许把flash中的指令当做数据(即const型的数据)。 三、冯诺依曼结构和哈佛结构的优缺点在典型情况下,完成一条指令需要3个步骤,即:取指令、指令译码和执行指令。从指令流的定时关系也可看出冯·诺依曼结构与哈佛结构处理方式的差别。举一个最简单的对存储器进行读写操作的指令,指令1至指令3均为存、取数指令,对冯·诺曼结构处理器,由于取指令和存取数据要从同一个存储空间存取,经由同一总线传输(因为只有一个存储空间RAM,因此只需要一种总线),因而它们无法重叠执行,只有一个完成后再进行下一个。因此,需要执行3*3=9次(每个指令一次执行:读取指令,解析指令,执行指令也即存数据)。哈佛结构则不同。中央处理器首先到ROM中读取程序指令内容,解码后得到数据地址,再到相应的数据存储器中读取数据,这个时候由于是对RAM进行操作,占用的是数据总线,因此CPU可以继续读取ROM中的指令,因此,执行过程是:CPU在做的工作 数据总线 指令总线读取指令1 空闲 占用分析指令1 空闲 空闲执行指令1,并读取指令2 占用 占用分析指令2 空闲 空闲执行指令2,并读取指令3 占用 占用 如上图,哈佛结构执行指令的时候,有一个”并发“的概念在里面。同时,哈佛结构的程序指令存储和数据存储分开,可以使指令和数据有不同的数据宽度,如Microchip公司的PIC16芯片的程序指令是14位宽度,而数据是8位宽度。但是,哈佛结构的CPU需要两套总线,设计起来比较复杂,十分不适合外围存储器的扩展;而冯诺依曼结构的是一条总线,设计起来简单,因此早期的市场还是被冯诺依曼结构占据的。而作为简单的单片机而言,由于内部集成了所需的存储器,所以采用哈佛结构也未尝不可。 四、其他的杂七杂八的内容,以及近代技术的一些发展当然,虽然从理论上来说,哈佛结构的数据应该放在RAM中,程序应该放在ROM中。但是,一般而言FLASH的读取速度要小于RAM(NAND FLASH的读取速度大约是在20-30M/s,NOR FLASH的读取速度和普通的SRAM等等差不多,好像可以达到G级别,当然,目前没有准确的数据支撑,只是道听途说)。因此,DSP作为高速信号处理的东东,对于程序的运行速度要求特别高。于是,尽管它是哈佛架构,大家就把程序从FLASH中读取到RAM中,再从RAM中运行。这样,从本质上来说,已经是有点接近于冯诺依曼结构了。而现代的X86系列处理器虽然外部总线上看是诺依曼结构的,但是由于内部CACHE的存在,因此实际上内部来看已经算是改进型哈佛结构的了(先利用其他模块将指令读到CACHE中,然后就相当于一个程序存储空间CACHE和一个数据存储空间RAM了)。因此,从某个角度来说,现代的冯诺依曼结构和哈佛结构,已经是越来越相似了。