关于arm中ZI-data段和RW-data段,以及堆栈起始地址的理解

stm32学习中,在keil中编译时可以看到 这些段的信息

在这里插入图片描述
这些段的知识网上讲解很多
ro-data段 只读段 一般常量const、“字符串”等;和代码段一样是存储在flash中;不加载到ram,不过也可以,我们stm中是不加载的;可以看看linux下的ld链接程序,什么bss段、data段、code段很清楚;
RW-data:已初始化的全局变量;这个是我们程序运行是要搬运到ram的段,且在程序开始执行时就进行rw段的搬运工作;
最关建的是ZI-data段!!!zi-data段是没有初始化,,不占flash存储,只需要在ram中开辟出空间,出事化为0即可。上述所说都是指全局变量,或者静态变量static,局部变量是在堆栈中的,可以直接说是栈中吧?!!不过堆和栈没有明确的界限都在堆栈区,不过栈是向下生长的,堆是向上生长的,当两者重叠时你的程序就死机了吧。。。
言归正传,讨论为什么上述的ZI-data是这么大呢,而不见堆栈大小的信息呢?其实这里的ZI-data已经包含了堆栈的大小了。。反正都是开辟内存。就是不知道开辟出来的内存,有的需要初始化??因为网上看到,初始化为0的全局数据也在这里,但是就不能统一的开辟内存了啊,这里没有用到内存管理不是C语言中的malloc的意思,只是将SP指针向后(地址增大方向)移动。我个人倾向于出事话为0的段也在ZW-data中,因为为了使ZI-data能统一分配,或者网上有人说初始化为零的段XX也在ZI-data段中,是错的!!!,我刚刚验证了,添加一全局变量=0,RW-data增加,所以初始化为0的变量依然在RW-data段中!!!!,但是你要是定义了全局变量,但是后面没有在函数中使用编译器就会优化掉,RW-data数值不增加,大家可以试试,实践出真知。
运行时的内存各段分配图 我用的是STM32F103 开发板,内部SRAM大小64k,地址从0x20000000开始
图1
关于arm中ZI-data段和RW-data段,以及堆栈起始地址的理解_第1张图片
本例中栈顶地址0x20000770 这是rw-data和ZI-data段的和。
在启动文件startup_stm32f10x_hd.s中定义堆、栈大小
关于arm中ZI-data段和RW-data段,以及堆栈起始地址的理解_第2张图片
我们可以看到这里栈大小 0x400 堆大小0x200 而前面ZI-data值为1848 十进制转换为16进制为0x738

我们改变 栈大小为 0x500

关于arm中ZI-data段和RW-data段,以及堆栈起始地址的理解_第3张图片
可以看到 ZI-data值变为 2104 16进制为0x838 说明栈大小包含在了ZI-data中,改变堆大小也是一样,堆栈大小包含在了ZI-data段中;

好了我们从内存图1的栈顶地址是怎么来的就是RW+ZI的值,前面例子,(10进制)rw=56,ZI-data=1848,加起来刚好是0x770,得到栈顶地址为0x20000770;
我们调试时可以看到sp的值为0x20000770
关于arm中ZI-data段和RW-data段,以及堆栈起始地址的理解_第4张图片
当然我们也可以通过映像文件查看,程序栈顶地址:
hex可以通过notepad++打开:bin文件用UE吧;
关于arm中ZI-data段和RW-data段,以及堆栈起始地址的理解_第5张图片映像文件第一个字(32bit)为程序栈顶地址,后面跟的是复位向量也就是程序入口。由于arm是小端模式,第一个字存储数据是0x20000770。

你可能感兴趣的:(嵌入式学习之旅)