STM32的分区从0x2000 0000开始。静态区,堆,栈。

所有的全局变量,包括静态变量之类的,全部存储在静态存储区。
紧跟静态存储区之后的,是堆区(如没用到malloc,则没有该区),之后是栈区,栈在程序中存储局部变量

先看启动文件startup_stm32f10x_md.s的定义:

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size EQU 0x00000400

AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp

; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size EQU 0x00000200

AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit

PRESERVE8
THUMB

这里定义了堆栈各自大小,堆:512bytes 栈1k;

所以栈区大小有限制,我们在局部变量中不要定义大数组否则容易溢出。

再看下code ro rw zi

cede:代码    ro也就是常量  rw已初始化的全局变量  zi未初始化的全局变量+栈

编译一个没有用malloc的工程:

查看.map文件:

Removing Unused input sections from the image. 
Removing startup_stm32f10x_md.o(HEAP), (512 bytes).    因为没有使用malloc,没有分配堆

Image Symbol Table

Symbol  Name                  Value Ov          Type          Size            Object(Section)

__initial_sp                  0x20000960        Data            0           startup_stm32f10x_md.o(STACK) 
STACK                         0x20000560       Section     1024           startup_stm32f10x_md.o(STACK)

__initial_sp 栈顶地址,躺在0x0800 0000占用四个字节,多说一句 0x0800 0004才是复位向量地址

STACK是栈底,__initial_sp -STACK=0x400 1k字节

==============================================================================

Code (inc. data)       RO Data    RW Data    ZI Data      Debug

39562    2998           3550          292           2108        641228   Grand Totals 
     39562    2998           3550          292           2108        641228   ELF Image Totals 
     39562    2998           3550          292              0             0          ROM Totals

==============================================================================

Total RO  Size (Code + RO Data)                        43112 (  42.10kB) 
    Total RW  Size (RW Data + ZI Data)                   2400 (   2.34kB) 
    Total ROM Size (Code + RO Data + RW Data)      43404 (  42.39kB)

==============================================================================

Total RW  Size (RW Data + ZI Data)              2400 (   2.34kB) : 也就是0x960 为栈顶__initial_sp      0x20000960

再加入malloc看一下:

要在编译选项中启用微库,include<stdlib.h>

int *p=NULL; 
p=malloc(sizeof(int));

HEAP                                      0x20000568   Section      512    startup_stm32f10x_md.o(HEAP) 
STACK                                    0x20000768   Section     1024   startup_stm32f10x_md.o(STACK) 
 __heap_base                         0x20000568   Data           0       startup_stm32f10x_md.o(HEAP) 
 __heap_limit                          0x20000768   Data           0       startup_stm32f10x_md.o(HEAP) 
 __initial_sp                             0x20000b68   Data           0      startup_stm32f10x_md.o(STACK)

可见分配了堆,大小为512 bytes在栈的下面,这里也可以看出,堆向上增长,栈向下增长

==============================================================================

Code (inc. data)      RO Data     RW Data     ZI Data     Debug

39770    3014          3550        300            2620         395376 Grand Totals
39770    3014          3550        44              2620         395376 ELF Image Totals (compressed)
39770    3014          3550        44                0             0 ROM Totals

==============================================================================

Total RO Size (Code + RO Data)                         43320 ( 42.30kB)
Total RW Size (RW Data + ZI Data)                    2920 ( 2.85kB)
Total ROM Size (Code + RO Data + RW Data)      43364 ( 42.35kB)

==============================================================================

Total RW Size (RW Data + ZI Data)                    2920 ( 2.85kB)    0xB68 栈顶

ZI变为2620比之前例子增加了512bytes 刚好是heap堆的大小

在map中:

==============================================================================

Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name

36          8             236            0              1536          0         startup_stm32f10x_md.o

==============================================================================

堆也在ZI中。

2920-2400=520 多了个堆512之后还有个8多到哪了?而且可以看到两次之间ZI只增加了堆的512,RW增加了8.

再次查看RW之后发现多了这个:

Image component sizes

==============================================================================

Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name

0          0          0                   8          0                 0              mvars.o

==============================================================================

还有一个问题  ELF Image Totals和Grand Totals之间RW少了256不过ELF Image Totals 变成了ELF Image Totals (compressed)

找到:http://www.keil.com/support/man/docs/armlink/armlink_CACHFGGB.htm

极好 的网址感谢网友

ELF Image Totals

If you are using RW data compression (the default) to optimize ROM size, the size of the final image changes and this is reflected in the output from --info. Compare the number of bytes under Grand Totals and ELF Image Totals to see the effect of compression.

In the example, RW data compression is not enabled. If data is compressed, the RW value changes.

Object Totals

Shows how many bytes are occupied by objects linked together to generate the image.

(incl. Generated)

armlink might generate image contents, for example, interworking veneers, and input sections such as region tables. If the Object Totals row includes this type of data, it is shown in this row.

In the example, there are 19 bytes of RO data in total, of which 16 bytes is linker-generated RO data.

Grand Totals

Shows the true size of the image. In the example, there are 10200 bytes of ZI data (in Object Totals) and 300 of ZI data (in Library Totals) giving a total of 10500 bytes.

最后附上关于RO,RW, ZI  Total ROM Size等的详细说明,摘抄

Code指存储到flash【Rom】中的程序代码。

     ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。

    RW是可读可写变量,就是初始化时候就已经赋值了的,RW + ZI就是你的程序总共使用的RAM字节数。

    RO是程序中的指令和常量,这些值是被保存到Rom中的。

    Total ROM Size (Code + RO Data + RW Data)这样所写的程序占用的ROM的字节总数,也就是说程序所下载到ROM flash 中的大小。为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。

 实际上,ROM中的指令至少应该有这样的功能:
         1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
         2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。
       

         在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。

STM32 的堆栈静态区的更多相关文章

  1. java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  2. 3.2 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  3. c语言中静态区,栈,堆的理解

    对于程序员,一般来说,我们可以简单的理解为内存分为三个部分:静态区,栈,堆. 很多书没有把把堆和栈解释清楚,导致初学者总是分不清楚. 其实堆栈就是栈,而不是堆. 堆的英文是heap:栈的英文是stac ...

  4. 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法

    堆区:专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中) 1.存储的全部是对象 ...

  5. 从内存的角度观察 堆、栈、全局区(静态区)(static)、文字常量区、程序代码区

    之前写了一篇堆栈的,这里再补充下内存其他的区域 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) — 一般由程 ...

  6. 【C/C++学院】0724-堆栈简单介绍/静态区/内存完毕篇/多线程

    [送给在路上的程序猿] 对于一个开发人员而言,可以胜任系统中随意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并能够运用到系统中.由此简化系统的开发.是其架构生涯的第一步. ...

  7. 【转】 Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method)

    JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令 ...

  8. C语言内存四区的学习总结(一)---- 静态区

    最近重新学习C语言相关知识,重新提到内存四区的概念,那么在之前的学习的基础上,在这儿做一个简单的总结与分享. 一.内存四区建立的流程 可以简单直观的查看下面的这个图片,直接的说明我们的程序在内存中是如 ...

  9. 内存布局:栈,堆,BSS段(静态区),代码段,数据段

    简介 我们程序运行的时候都是放在内存里的.根据静态.成员函数.代码段.对象.等等.放在不同的内存分块里.大概分为5块 1  栈 2  堆 3 BSS段-全局区-(静态区) 4 代码段 5 数据段 栈 ...

随机推荐

  1. MySQL-----改

    改 **修改用户名** rename user 'username'@'IP address' to 'new username'@'IP address'; **修改密码** set passwor ...

  2. 06-看图理解数据结构与算法系列(AVL树)

    AVL树 AVL树,也称平衡二叉搜索树,AVL是其发明者姓名简写.AVL树属于树的一种,而且它也是一棵二叉搜索树,不同的是他通过一定机制能保证二叉搜索树的平衡,平衡的二叉搜索树的查询效率更高. AVL ...

  3. python接口自动化测试(一)

    本节开始,开始介绍python的接口自动化测试,首先需要搭建python开发环境,到https://www.python.org/下载python 版本直接安装就以了,建议 下载python2.7.1 ...

  4. xtu summer individual 6 D - Checkposts

    Checkposts Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Orig ...

  5. HDU 2647 逆向拓扑排序

    令每一个员工都有一个自己的等级level[i] , 员工等级越高,那么工资越高,为了使发的钱尽可能少,所以每一级只增加一单位的钱 输入a b表示a等级高于b,那么我们反向添加边,令b—>a那么i ...

  6. [K/3Cloud] 创建一个单据转换插件

    概念: 创建一个业务单据转换插件,在单据转换的各个时点干预单据转换的相关逻辑控制. 示例: 新建一个类,继承自单据转换插件基类Kingdee.BOS.Core.Metadata.ConvertElem ...

  7. 搭桥(codevs 1002)

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

  8. 【ZJOI2018 Round2游记】

    在主场作为高三退役选手要去听一些奇怪的宣讲 看看有没有PY的机会 语文考试考到一半溜出来 ZJU先上 开始挑衅 很勇啊 THU的校友 然而这些都离我太过遥远 最后PY了一波 获得了鼓励(并不) 最后的 ...

  9. Layui选项卡、进度条、面板、徽章、时间线、辅助元素

    Layui选项卡.进度条.面板.徽章.时间线.辅助元素 Tab选项卡 - 页面元素    导航菜单可应用于头部和侧边,Tab选项卡提供多套风格,支持响应式,支持删除选项卡等功能.面包屑结构简单,支持自 ...

  10. 【转】关于easyui tab 加载 js ajax 不走后台的问题, 怕找不到 以防万一

    一直以来群里里面很多人反应,在用tab加载界面的时候,界面里面的js不会执行.今天在此说明一下原因. 不管是window,dailog还是tab其实质最终都是继承了panel.panel有两种方式展示 ...