STM32启动过程分析
1.1 STM32的程序在flash上的存储结构
1.2 STM32的数据在SRAM上的存储结构
Code是代码占用的空间;
RO-data是 Read Only 只读常量的大小,如const型;
RW-data是(Read Write) 初始化了的可读写变量的大小;
ZI-data是(Zero Initialize) 没有初始化的可读写变量的大小。ZI-data不会被算做代码里因为不会被初始化;(ZI是指zero-initialized)
简单的说就是在烧写的时候是FLASH中的被占用的空间为:Code + RO Data + RW Data
程序运行的时候,芯片内部RAM使用的空间为: RW Data + ZI Data
我在纳闷儿,上面的描述中为什么没有栈和堆的概念?因为上面描述的是程序运行前的内存分配,而堆和栈是程序运行时才分配空间的,而且堆和栈有专门的存储区域,
可执行文件在内存运行时由栈**,堆,数据段(由三部分部分组成:只读数据段(.rodata),已经初始化读写数据段(.data),未初始化数据段即BBS)和代码段组成,**
C语言的内存管理(代码段、数据段,栈,堆)
C语言程序分为映像和运行两种状态。
经过编译连接后形成的映像由:代码段(text) 数据段(data 包括RO data ,RW data), 其他段(调试的段,动态库共享库链接表的段)组成。
可执行文件在内存运行时由栈,堆,数据段(由三部分部分组成:只读数据段(.rodata),已经初始化读写数据段(.data),未初始化数据段即BBS)和代码段组成,如下图所示:
所以:数据区 = .rodata .data .bss
.rodata = 文字常量区
全局区和静态区指的是 .data 和 .bss区
https://blog.csdn.net/weixin_42108004/article/details/84581073?ops_request_misc=&request_id=&biz_id=102&utm_term=c%E8%AF%AD%E8%A8%80%E6%95%B0%E6%8D%AE%E6%AE%B5&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-84581073.pc_search_result_control_group&spm=1018.2226.3001.4187
原文链接:https://blog.csdn.net/weixin_39964178/article/details/82875304
C语言内存分区_栈区、堆区、全局&静态区、文字常量区、程序代码区
栈区:
在函数中定义的变量存放的内存区域。
常见的int、float、char等变量均存放于栈区中,它的特点是由系统自动分配与释放,不需要程序员考虑资源回收的问题,方便简洁。
ps:栈区的地址分配是从内存的高地址开始向地地址分配。
堆区:
程序员通过指令自主向系统申请的内存区域,大小由程序员决定,它在使用完后同样需要程序员通过指令去释放该区域内存,否则将有可能出现内存的浪费与溢出。
C语言中申请堆区指令为:
int *p = (int *) malloc( N * sizeof(int) ); //分配N个int型(4字节)的内存,即 4 * N 个字节
ps:但指针p存放于栈区。
C语言中释放堆区指令为:
free( p ); //注意此处参数为指针
使用中应该注意,尽量不要去修改p指针对应的地址值,否则在内存释放时将出现错误。(编译可通过,运行出现问题)
全局变量&静态变量区:
全局变量与静态变量本应是两个概念,但由于它们在内存中存放的区域相同,所以将他们放在一起讨论。
全局变量:
位于所有函数外部定义的变量,在整个工程中可见,可修改。
静态变量:
位于所有函数内部定义的由 static 修饰的变量,仅在定义的函数中可见,可修改。(这是它与全局变量的关键区别)
ps:静态变量仅在第一次创建时初始化一次,之后自动跳过初始化语句。
全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。(堆区与栈区则不会)
文字常量区:
用于存放文字等不可修改的常量,由系统分配和释放内存。
常见的使用:
char *s = “HelloWorld”;//该字符串 HelloWorld 即存放于文字常量区,不可修改
ps:但指针s存放于栈区。
pps:若在程序中尝试对其修改(例如尝试修改第一个字符 *s = ‘h’;),将出现编译可通过,运行报错的情况。
同时因注意它与const修饰的变量之间的区别:
char aa = ‘A’;//aa存放于栈区
const char bb = ‘B’; //bb同样存放于栈区
const修饰的变量仅仅用于告诉编译器bb是一个常量,如果后续的程序中有出现尝试修改bb的操作时,编译将报错。
这种写法主要是为了防止程序员在后续的代码中误操作bb变量而添加的一个约束条件,并不会影响它存放的位置。
程序代码区:
用于存储程序编译连接后生成的二进制机器码指令的内存区域。该部分内容可通过反汇编操作将机器码转换为汇编语言。
C语言分为五大内存分区:
1、栈区(stack): —由编译器自动分配释放,存放函数的参数值,局部变量的值等。
2、堆区(heap): 一般由程序员分配释放,若程序员不释放,程序结束时由系统释放。
3、全局区(静态区,static): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
4、文字常量区: 常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区: 存放函数体的二进制代码。
注:全局变量&静态变量区:
全局变量与静态变量本应是两个概念,但由于它们在内存中存放的区域相同,所以将他们放在一起讨论。
全局变量:
位于所有函数外部定义的变量,在整个工程中可见,可修改。
静态变量:
位于所有函数内部定义的由 static 修饰的变量,仅在定义的函数中可见,可修改。(这是它与全局变量的关键区别)
ps:静态变量仅在第一次创建时初始化一次,之后自动跳过初始化语句。
全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。(堆区与栈区则不会)
原文链接:https://blog.csdn.net/Filter_CPH/article/details/48524249
学过C语言的应该都知道程序分区这个概念,只是可能不是那么的熟悉,下面就简要的谈论一下C程序的分区
。
比如在一个C程序中写一个i全局变量int a = 10;那么这个整形变量a存放在哪儿,又或者是函数中定义的,又该放在哪儿。
1、未初始化的全局变量和初始化为0的全局变量(.bss 段)
bss类型的全局变量只占运行时的内存空间,而不占用文件空间。存在于整个程序运行过程中。
2、初始化过且非零的全局变量(.data 段)
data类型的全局变量既占文件空间又占用运行时的内存空间。存在于整个程序运行过程中。
3、常量数据(.rodata 段)
常量不一定放在.rodata段,有的立即数与指令编码在一起放在.text 段中。
对于一个字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件中只存在一份复制。
.radata在多个进程间是共享的,提高运行空间利用率。
修改常量会出现段错误。
一些系统中会把rodata放在ROM中(或者NOR Flash),运行时直接读取,无需加载到RAM中。
4、代码(.text 段)
存放代码和部分整数常量,和.rodata段相似,主要不同的是这个段可以执行。
5、栈(stack)
可以用于实现函数的调用,管理临时变量。
栈向下增长。
6、堆(heap)
由程序员手动分配和释放的一块内存区域。
注意malloc、realloc、free的用法。这里不再详细讲解。
原文链接:https://blog.csdn.net/m0_37968915/article/details/72801134
1.初始化和未初始化的全局变量存储在哪个区域?
C规定,未初始化变量的初值为0,这个清0的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。
为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。
而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。
一.初始化的全局变量存放在数据段(data segment),数据段数据静态分配
二.未初始化的全局变量存放在bss段,BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
“未初始化”这一说法其实并不准确,虽然.bss段在编译出的目标文件中是不占 空间的,但是c语言假设在程序的执行之前,运行时启动代码或者操作系统会负责将.bss段清零,而且许多c语言都依赖这一特性。
三.BSS是英文Block Started by Symbol的简称
四.在编译后的目标文件中不占有空间
原文链接:https://blog.csdn.net/weiyuanke/article/details/7645129
2.例:char *A = “helloworld”;
问:A存储在呢个区域? 看A定义在函数内还是函数外
“helloworld”存储在那个区域? 文字常量区