[经验分享] 关于keil中内存分配的问题,局部变量、全局变量,堆栈的分配

[复制链接]
6462|61
 楼主| dzfansman 发表于 2023-11-14 22:04 | 显示全部楼层 |阅读模式
看.map文件



从.map文件中可以看出,ram中的数据是如何摆放的:
1.首先从0x20000000开始,放全局变量的数据,如上图2所示,0x20000000以及0x200000004/0x20000008的地方的数据,存放的是全局变量,分别是uart_rxdata、FM_Freq等。
2.放完全局变量之后是用static声明的局部变量,如图1中的n,max_num以及times等,这些在c代码中都是用static声明的局部变量
3.放完这些数据之后,也就是静态存储区结束之后,是堆,根据启动文件,分配堆的空间。
4.堆空间结束后是栈,如图2中的initial_sp,从堆结束继续数0x400后作为栈顶。(注:0x400是在启动文件中设置的栈的大小,自己设定,我这里没有使用堆,编译器貌似优化掉了,因此直接从静态存储区直接数了0x400作为栈区)

总结

画个图


qcliu 发表于 2023-12-5 16:39 | 显示全部楼层
希望楼主可以把分享的图片贴一下看看
tpgf 发表于 2023-12-5 17:30 | 显示全部楼层
一般来keil的配置里边也可以做一些工作
drer 发表于 2023-12-6 13:00 | 显示全部楼层
在map文件里边可以看到所有种类存储的信息吗
coshi 发表于 2023-12-6 13:51 | 显示全部楼层
在map里边我们只能进行查看,那么如何进行修改呢
kxsi 发表于 2023-12-6 14:38 | 显示全部楼层
通过map文件我们只能看到大概的分布
wiba 发表于 2023-12-6 15:29 | 显示全部楼层
.map文件支持用户自行更改吗?
vivilyly 发表于 2024-1-6 16:27 | 显示全部楼层
全局变量通常分配在RAM的起始位置,这个区域也被称为全局变量区。当程序编译后,全局变量的地址就被确定下来,并且相对这个地址是唯一的,也就是说,同一个地址不会分配给另一个全局变量。全局变量在程序启动时由启动代码初始化,并且在整个程序运行期间保持不变。
albertaabbot 发表于 2024-1-6 17:29 | 显示全部楼层
堆是一个特殊的内存区,用于存放由malloc、calloc、realloc等函数分配的动态内存。在程序运行时,可以根据需要申请和释放这块内存。堆的大小在启动配置时设定,如果程序中使用了动态内存分配,那么编译器会在链接阶段为堆分配空间。
eefas 发表于 2024-1-6 18:53 | 显示全部楼层
在Keil编译器下编程时,全局变量分配在静态数据区,局部变量默认分配在栈上,而动态分配的内存位于堆区。
uiint 发表于 2024-1-6 19:44 | 显示全部楼层
局部变量是在函数内部声明的变量,其作用域仅限于函数内部。局部变量通常存储在堆栈(Stack)区域。在函数调用时,堆栈会为局部变量分配内存空间。当函数执行完毕后,这些内存空间将被释放。局部变量的内存分配和释放由编译器自动完成。
wangdezhi 发表于 2024-1-6 21:54 | 显示全部楼层
栈和堆的大小足够,以避免溢出和内存分配失败。
dspmana 发表于 2024-1-6 22:09 | 显示全部楼层
堆(heap)是由程序员手动分配和释放的内存区域,用于动态内存分配。
堆内存的分配和释放通常使用malloc、calloc、realloc和free等函数。
堆内存的分配是动态的,可以在程序的任何时候进行,但程序员必须确保及时释放不再使用的内存,以避免内存泄漏。
burgessmaggie 发表于 2024-1-6 22:21 | 显示全部楼层
可以在启动文件里设置栈的大小。              
ingramward 发表于 2024-1-7 22:29 | 显示全部楼层
在嵌入式系统中,由于内存资源有限,合理地使用全局变量和避免过度使用堆栈是很重要的。过多的全局变量或过大的堆栈使用可能导致内存溢出或其他问题。
youtome 发表于 2024-1-7 22:42 | 显示全部楼层
全局变量是在所有函数外部定义的变量,其作用域是整个程序,可以由程序中的任何函数访问。相对地,局部变量是在某个特定函数内部定义的变量,只能由该函数内部的语句访问,且只能在该函数被调用时存在。
beacherblack 发表于 2024-1-8 13:10 | 显示全部楼层
在Keil的内存视图中,你可以看到类似以下的分配情况:

RAM中的数据是从0x20000000开始摆放全局变量的数据。
0x20000000以及0x20000004、0x20000008的地方的数据,存放的是全局变量,如uart_rxdata、FM_Freq等。
静态变量也放在RAM中,初始化过的静态变量放在.data段,未初始化的静态变量放在.bss段。
栈(CSTACK)用于存放局部变量和函数参数,局部变量超过栈大小将会发生栈溢出。
houjiakai 发表于 2024-1-8 13:59 | 显示全部楼层
在Keil中,可以使用链接脚本配置这些内存区域的大小和位置,以确保程序的正确运行。
louliana 发表于 2024-1-8 15:12 | 显示全部楼层
堆栈是一种特殊的内存区域,用于存储局部变量、函数调用的返回地址、参数等信息。在Keil中,堆栈的大小可以在启动文件(Startup File)中设置。在程序运行过程中,堆栈的使用情况可以通过.map文件进行查看。在调试模式下,可以使用Keil的调试器查看堆栈的使用情况。
benjaminka 发表于 2024-1-8 15:44 | 显示全部楼层
每个函数都有自己的栈帧,用于存储局部变量、函数参数、返回地址等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

2023

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部