打印
[经验分享]

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

[复制链接]
4126|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文件里边可以看到所有种类存储的信息吗

使用特权

评论回复
5
coshi| | 2023-12-6 13:51 | 只看该作者
在map里边我们只能进行查看,那么如何进行修改呢

使用特权

评论回复
6
kxsi| | 2023-12-6 14:38 | 只看该作者
通过map文件我们只能看到大概的分布

使用特权

评论回复
7
wiba| | 2023-12-6 15:29 | 只看该作者
.map文件支持用户自行更改吗?

使用特权

评论回复
8
vivilyly| | 2024-1-6 16:27 | 只看该作者
全局变量通常分配在RAM的起始位置,这个区域也被称为全局变量区。当程序编译后,全局变量的地址就被确定下来,并且相对这个地址是唯一的,也就是说,同一个地址不会分配给另一个全局变量。全局变量在程序启动时由启动代码初始化,并且在整个程序运行期间保持不变。

使用特权

评论回复
9
albertaabbot| | 2024-1-6 17:29 | 只看该作者
堆是一个特殊的内存区,用于存放由malloc、calloc、realloc等函数分配的动态内存。在程序运行时,可以根据需要申请和释放这块内存。堆的大小在启动配置时设定,如果程序中使用了动态内存分配,那么编译器会在链接阶段为堆分配空间。

使用特权

评论回复
10
eefas| | 2024-1-6 18:53 | 只看该作者
在Keil编译器下编程时,全局变量分配在静态数据区,局部变量默认分配在栈上,而动态分配的内存位于堆区。

使用特权

评论回复
11
uiint| | 2024-1-6 19:44 | 只看该作者
局部变量是在函数内部声明的变量,其作用域仅限于函数内部。局部变量通常存储在堆栈(Stack)区域。在函数调用时,堆栈会为局部变量分配内存空间。当函数执行完毕后,这些内存空间将被释放。局部变量的内存分配和释放由编译器自动完成。

使用特权

评论回复
12
wangdezhi| | 2024-1-6 21:54 | 只看该作者
栈和堆的大小足够,以避免溢出和内存分配失败。

使用特权

评论回复
13
dspmana| | 2024-1-6 22:09 | 只看该作者
堆(heap)是由程序员手动分配和释放的内存区域,用于动态内存分配。
堆内存的分配和释放通常使用malloc、calloc、realloc和free等函数。
堆内存的分配是动态的,可以在程序的任何时候进行,但程序员必须确保及时释放不再使用的内存,以避免内存泄漏。

使用特权

评论回复
14
burgessmaggie| | 2024-1-6 22:21 | 只看该作者
可以在启动文件里设置栈的大小。              

使用特权

评论回复
15
ingramward| | 2024-1-7 22:29 | 只看该作者
在嵌入式系统中,由于内存资源有限,合理地使用全局变量和避免过度使用堆栈是很重要的。过多的全局变量或过大的堆栈使用可能导致内存溢出或其他问题。

使用特权

评论回复
16
youtome| | 2024-1-7 22:42 | 只看该作者
全局变量是在所有函数外部定义的变量,其作用域是整个程序,可以由程序中的任何函数访问。相对地,局部变量是在某个特定函数内部定义的变量,只能由该函数内部的语句访问,且只能在该函数被调用时存在。

使用特权

评论回复
17
beacherblack| | 2024-1-8 13:10 | 只看该作者
在Keil的内存视图中,你可以看到类似以下的分配情况:

RAM中的数据是从0x20000000开始摆放全局变量的数据。
0x20000000以及0x20000004、0x20000008的地方的数据,存放的是全局变量,如uart_rxdata、FM_Freq等。
静态变量也放在RAM中,初始化过的静态变量放在.data段,未初始化的静态变量放在.bss段。
栈(CSTACK)用于存放局部变量和函数参数,局部变量超过栈大小将会发生栈溢出。

使用特权

评论回复
18
houjiakai| | 2024-1-8 13:59 | 只看该作者
在Keil中,可以使用链接脚本配置这些内存区域的大小和位置,以确保程序的正确运行。

使用特权

评论回复
19
louliana| | 2024-1-8 15:12 | 只看该作者
堆栈是一种特殊的内存区域,用于存储局部变量、函数调用的返回地址、参数等信息。在Keil中,堆栈的大小可以在启动文件(Startup File)中设置。在程序运行过程中,堆栈的使用情况可以通过.map文件进行查看。在调试模式下,可以使用Keil的调试器查看堆栈的使用情况。

使用特权

评论回复
20
benjaminka| | 2024-1-8 15:44 | 只看该作者
每个函数都有自己的栈帧,用于存储局部变量、函数参数、返回地址等。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

2023

帖子

0

粉丝