文章出处。 http://blog.csdn.net/qq_29344757/article/details/75730054
从在学校到后来的实习工作,讲真,对于处理器的冯诺依曼结构和哈佛结构不大在意,印象中只知道它是数据存储器和程序存储器相关。
昨天在STM32程序中,把全局变量的定义成const属性时,发现它所处的位置是在STM32内置的FLASH而非内置的SRAM中。顿时让我觉得十分奇怪,程序不都必须在RAM中运行?即使在静态常量区不也应该放在SRAM中?
原因?这得从处理器的冯诺依曼和哈佛结构说起了。
1. 哈佛结构和冯诺依曼结构
哈佛结构,指的是数据存储器和程序存储器在物理是是分离的,以51单片机为例,数据存储器是单片机的RAM,程序存储器是单片机的ROM。在数据存储器中上不允许存储指令,同理,在指令存储器上不允许存储数据。
图为网上哈佛结构示意,数据存储器和程序存储器分别使用独立的两条总线,控制单元能够同时与程序存储器、数据存储器通信,实现软件系统功能。ARM采用的就是哈佛结构。(严格来说,很多高级ARM芯片已经采用哈佛结构和冯诺依曼结构的结合了)
冯诺依曼结构,通用计算机采用就是这种结构,数据和程序存储器不分离:
可以看出冯诺依曼把数据存储器和程序存储器都放在memory当中。对冯诺依曼结构而言,在执行程序时必须将指令和数据加载到运行内存中。
两种结构在保护代码区应该有不同的实现,哈佛结构在硬件级别上对代码和数据进行区分,当然软件应该也有,而冯诺依曼结构时应该单纯靠软件级别上进行区分的。
2. STM32的const全局变量地址
程序如下:
const int globalConstDat = 12;
int globalDat = 11;
int main(void)
{
int localDat = 6;
const int localConstDat = 7;
USART_Configuration();
//ptint to PC from USART1
printf("&globalConstDat = 0x%p, &globalDat = 0x%p\r\n\r\n", &globalConstDat, &globalDat);
printf("&localDat = 0x%p, &localConstDat = 0x%p\r\n", &localDat, &localConstDat);
while(1);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
程序运行结果:
根据STM32的存储器映像图(在 STM32启动文件一文配有此图),可得出,globalConstDat的地址位于Flash memory(0x0800 0000~0x0801 ffff),其它变量的地址位于SRAM。为什么会有这种情况?第一取决编译器,第二则是因为ARM是哈佛结构。内置的FLASH和内置的SRAM相当于51单片机的ROM和RAM。SRAM用于存放数据,FLASH用于存放指令。在程序运行的时候,控制单元可以同时和RAM、FLASH通信,也就是说CPU可以直接在FLASH执行程序。注意,有些FLASH是不可以直接在其上去执行程序的,需要加载到RAM来,比如NandFlash,因为读取NandFlah的速度非常慢,但是也有一些FLASH可以,比如NorFlah。STM32内置的FLASH就是类似NorFlash属性的FLASH。全局静态常量是在文本常量区,它是静态且不可修改的,被编译器安排在了程序存储区,也就是说被编译给“指令化”了。
若是在冯诺依曼结构的处理器中,这样的情况,编译器则会有另外一套处理措施了。