cisen / blog

Time waits for no one.
135 stars 20 forks source link

堆栈、BSS段、代码段、数据段、RO、RW、ZI等概念区分【转】 #886

Open cisen opened 4 years ago

cisen commented 4 years ago

最前言

一 预备知识

在区分一个程序的堆栈、bss、text段、RO、RW、ZI等概念时,首先区分一下程序进程和程序文件,然后了解一下哈弗结构和冯诺依曼结构。

程序进程就是程序运行时的程序,程序文件是编译后生成的可执行文件,比如.bin文件等,这两个概念很好区分,特别强调一下,分开表达主要是怕读者在阅读过程中混淆了。

哈佛结构和冯诺依曼结构的主要区别就是处理器能不能实现取指令和取数据的并发进行。嵌入式芯片中主要是哈佛结构,PC机上是冯诺依曼结构。

经典的哈佛结构:

程序存储器和数据存储器是各自独立的存储器。处理器应该有两套总线,一套是程序存储器的数据和地址总线,一套是数据存储器的数据和地址总线。取指令和取数据能并发进行。51的程序进程的逻辑代码段放在ROM中,而变量部分则放在RAM中,取ROM中的指令和RAM中的变量是两套总线。

改进型哈佛结构:

程序存储器和数据存储器是各自独立的存储器。处理器只有一套总线,分时访问程序存储器和数据存储器,但是在处理器中有icache和dcache将程序和数据分开,所以处理器仍然可以并步执行取指令和取数据。从ARM9开始以后所有的ARM处理器内核都是改进型的哈佛结构。ARM的逻辑代码和变量都是存放在RAM中的,但是,它在内存中划分了两部分的空间,其中一部分放逻辑代码,另一部分存放变量,之间不会相互干扰。

冯诺依曼结构:

没有程序存储空间和数据存储空间之分。处理器只有一套总线,取指令和取数据是不能同时进行的。程序进程全部在RAM中,他们之间一般是按照代码的执行顺序依次存储。由于全部在RAM中,运行速度快,所需的RAM多。

二 程序文件中的分区:

备注:只针对嵌入式,pc程序文件没有探究过。小标题“程序文件中的分区”其实不是很恰当,不知道该如何形容,此部分概念通常出现在一个程序编译完成后的大小统计,请自行理解。

相关概念:Code,RO_data,RW_data,ZI_data,RO,RW,常出现在嵌入式程序编译完成后的统计,例如MDK,IAR,ARM GCC。

有些技术文章中会直接使用RO,请注意区分RO和RO-data的区别。

当程序存储在ROM中时,所占用的大小为Code + RO_data + RW_data 。 当程序执行时, RW_data和 ZI_data在RAM中,RO_data和code视cpu架构(51、arm、x86)不同处于ROM或者RAM中。其中ZI_data对应了BSS段,RW_data对应数据段,code对应代码段, RO_data对应数据段。

三 程序进程中的分区:

相关概念:堆(heap),栈(stack),BSS段,数据段(data),代码段(code /text),全局静态区,文字常量区,程序代码区。

文字常量区—常量字符串就是放在这里的。 程序代码区—存放函数体的二进制代码。

针对上述概念,文章 https://www.cnblogs.com/huhuuu/p/3440187.html中具体描述了,例如对于初始化的全局变量和为初始化的全局变量,虽然分别属于数据段和BSS段,但在程序具体运行时,分配的内存地址是挨着的。同理,文字常量的地址也是连续的

四 总结 以上几个概念的对应关系如下表中所示: 备注:粉色部分的code和RO_data文字颜色为灰色,表示可能发生在ROM,也可能发生在RAM,根据架构不同而不同。

参考 https://blog.csdn.net/andylauren/article/details/52259652 https://www.cnblogs.com/huhuuu/p/3440187.html https://blog.csdn.net/qq_25827755/article/details/52297383 http://www.cnblogs.com/amanlikethis/p/3344558.html