思考: 如何判断一款CPU是冯诺依曼架构or哈佛架构

这个问题隶属于CPU设计的范畴

其等价问题为 CPU是如何获取指令和数据的,进一步的,指令和数据是否是分开存取的

普遍的说法是这样的,如果指令和数据分开存取,则是哈佛结构,否则是冯诺依曼结构

不要尝试去记忆这些结论,我们要去思考,去理解这个事情

以51内核的单片机为例,我们将编译后的bin文件烧录到片子里面,然后上电之后程序执行

看似简单的过程,里面也有一些我们不是很清楚的细节,一些记忆碎片没有完全联系起来

比如:

a.51单片机的norflash 有几十K

b.我们烧录进去的代码肯定包含指令和数据

c. 51 单片机的运行也是需要ram的,好像叫做sram

这个时候,问题逐渐变得清晰起来,我至少有以下几个问题要问:

1. 烧录的代码全部烧到norflash了吗,还是指令在flash, 数据在sram?

2. sram能掉电存储吗?

3. int main() { int a = 5; int b = 10; int c = a + b; return c;  } 这个例子中,5, 10是指令还是数据?

4. int main() { printf("helloworld "); return 0; } 这个例子中,"helloworld"是指令还是数据?

========================================================================

不问不知道,我在这么基础的问题上竟然还犯了错误:

首先,我的大前提中的b就犯了错误,烧录的code全是指令

其次,常识性的错误:sram不可掉电存储,代码全部烧到norflash中

所谓的数据是指运行时的概念,CPU run起来的时候会去访问ram, 通过寻址指令在cpu寄存器和ram中来回搬运数据

MOV R1,#00H的机器代码是 A8 00,一共两个字节,而且存储在ROM。
而你把MOV R1,#00H认为是两个部分是错误的,这是一个完整的指令(即存储在ROM),
不是说MOV是指令而后面的R1,#00H不是指令——你只是看表面上的内容,没有看其本质。
一条汇编指令的完整格式是[标号:]操作码[源操作数],[母的操作数][;注释],其中中括号内的可以省略

也就是说,问题3,4中的常量也是code的一部分, 只不过,涉及全局变量和常量字符串的code可能在链接脚本的处理上有点特殊

关于链接脚本,需要再开一个专栏讲解

回答了这些问题,单片机上电启动的图景才渐渐在脑海中清晰起来。

单片机上电后,CPU去norflash中的固定位置取第一条指令,然后译指执行,这个期间,一些存储计算等操作会用到ram, 那就必然涉及CPU访问ram。下图是51的系统结构框图

 
那这到底是不是哈佛结构呢?

看两点:一是程序和数据存储要分开,二是程序和数据要有单独的读取路径

很遗憾,51不满足第二点,它是公用了数据线 和地址线去访问指令和数据的

那谁是标准的哈佛结构呢,我们接触过的cortex-m3的单片机就是。

所以其实,后面会发现,现代的CPU都是混用这两种结构了,CPU和存储器并不直接相连,在cache外面,程序和数据是存在一起的

通过AHB总线访问,到了里面又会分开,指令是指令,数据是数据。

原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15388263.html