Limit 含义
了解RO,RW和ZI需要首先了解以下知识:
ARM程序的组成
此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别。
一个ARM程序包含3部分:RO,RW和ZI
RO是程序中的指令和常量
RW是程序中的已初始化变量
ZI是程序中的未初始化的变量
由以上3点说明可以理解为:
RO就是readonly,
RW就是read/write,
ZI就是zero

ARM映像文件的组成
所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。
Image文件包含了RO和RW数据。
之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
Q:为什么Image中必须包含RO和RW?
A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。

注意:如果一个变量被初始化为0,则该变量的处理方法与未初始化华变量一样放在ZI区域。
即:ARM C程序中,所有的未初始化变量都会被自动初始化为0。
总结:
1; C中的指令以及常量被编译后是RO类型数据。
2; C中的未被初始化或初始化为0的变量编译后是ZI类型数据。
3; C中的已被初始化成非0值的变量编译后市RW类型数据。

ARM程序的执行过程
从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。
实际上,ROM中的指令至少应该有这样的功能:
1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中
在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。

rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)STM32_SRAM_END);

用于初始化RT-thread系统的堆区域。

Image$$RW_IRAM1$$ZI$$Limit

是一个链接器导出的符号,代表ZI段的结束,也就是程序执行区的RAM结束后的(注意这个‘的’,有点i++和++i的意思)地址,反过来也就是我们执行区的RAM未使用的区域的起始地址(其实这里有点牵强,因为这样理解往往只是一个准寻的标准,以为在RAM的使用上ZI区往往是整个程序的最末尾,也许这里我理解错了)。

&Image$$RW_IRAM1$$ZI$$Limit

取地址。

例如:

Image$$RO$$Limit

:表示RO区末地址后面的地址,即RW数据源的起始地址

Image$$RW$$Base

:RW区在RAM里的执行区起始地址,也就是编译器选项RW_Base指定的地址

Image$$ZI$$Base

:ZI区在RAM里面的起始地址

Image$$ZI$$Limit

:ZI区在RAM里面的结束地址后面的一个地址

程序先把ROM里(Image$$RO$$Limt)开始的RW初始数据拷贝到RAM里面
(Image$$RW$$Base)开始的地址,当RAM这边的目标地址到达(Image$$ZI&&Base)后就表示RW区的结束和ZI区的开始,接下去就对这片ZI区进行清零操作,直到遇到结束地址。

  

ARM程序的RO段、RW段和ZI段 --Image的更多相关文章

  1. stm32 ARM中的RO、RW和ZI DATA

    一直以来对于ARM体系中所描述的RO,RW和ZI数据存在似是而非的理解,这段时间对其仔细了解了一番,发现了一些规律,理解了一些以前书本上有的但是不理解的东西,我想应该有不少人也有和我同样的困惑,因此将 ...

  2. ARM MDK 编译产生:RO、RW和ZI DATA说明

    1.比如编译一个工程文件,产生如下提示信息: Program Size: Code=18938 RO-data=622 RW-data=124 ZI-data=7724 RO段.RW段和ZI段 要了解 ...

  3. Keil开发的ARM程序main函数之前的汇编分析

    Keil开发的ARM程序main函数之前的汇编分析 ——BIN文件中RW段的数据移动 系统平台: STM32系列STM32F103ZE,512KB内部FLASH,64KB片内存储; FLASH地址范围 ...

  4. 载域和运行域的理解(ARM程序是怎么运行的)

    对ARM加载域和运行域的理解 一般而言,一个程序包括只读的代码段和可读写的数据段.在ARM的集成开发环境中,只读的代码段和常量被称作RO段(ReadOnly):可读写的全局变量和静态变量被称作RW段( ...

  5. KEIL的ARM编译器对RW和ZI段的一个处理

    按照C编译器编译的结果,一般会产生RO段,RW段,ZI段.RO是程序中的指令和常量,RW是程序中的已初始化全局变量,ZI是程序中的未初始化或初始化为零的全局变量. 那么如下的代码 int aaa; i ...

  6. 【转】RO段、RW段和ZI段 --Image$$??$$Limit 含义(zz)

    @2019-02-14 [小记] RO段.RW段和ZI段 --Image$$??$$Limit 含义(zz)

  7. 评《撸一段 SQL ? 还是撸一段代码? 》

    最近看到一篇博客<撸一段 SQL ? 还是撸一段代码?>,文章举例说明了一个连表查询使用程序code来写可读性可维护性更好,但是回帖意见不一致,我想作者在理论层面没有做出更好的论述,而我今 ...

  8. 数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11

    这篇博文,我们编写一个C语言的小程序,来解析数据段或者代码段描述符的各个字段.这样我们阅读原书的代码就会方便一点,只要运行这个小程序,就可以明白程序中定义的数据段或者代码段的描述符了. 这段代码,我用 ...

  9. 数据段描述符和代码段描述符(一)——《x86汇编语言:从实模式到保护模式》读书笔记10

    一.段描述符的分类 在上一篇博文中已经说过,为了使用段,我们必须要创建段描述符.80X86中有各种各样的段描述符,下图展示了它们的分类. 看了上图,你也许会说:天啊,怎么这么多段描述符啊!我可怎么记住 ...

随机推荐

  1. ElasticSearch 连载一 基础入门

    ElasticSearch简写ES,ES是一个高扩展.开源的全文检索和分析引擎,它可以准实时地快速存储.搜索.分析海量的数据. 应用场景 我们常见的商城商品的搜索 日志分析系统(ELK) 基于大量数据 ...

  2. 2019-ACM-ICPC-南京区网络赛-E. K Sum-杜教筛+欧拉定理

    2019-ACM-ICPC-南京区网络赛-E. K Sum-杜教筛+欧拉定理 [Problem Description] 令\(f_n(k)=\sum_{l_1=1}^n\sum_{l_2=1}^n\ ...

  3. JVM系列一:虚拟机内存区域

    虚拟机栈 1.虚拟机栈维护一个线程中所有方法的栈帧,每个栈帧中保存着这个方法中用到的局部变量表,操作数栈,常量引用 2.可以用-Xss来设置每个线程中虚拟机栈的大小,在jdk1.4之前默认虚拟机栈大小 ...

  4. Codeforces Round #511 (Div. 2) C. Enlarge GCD (质因数)

    题目 题意: 给你n个数a[1]...a[n],可以得到这n个数的最大公约数, 现在要求你在n个数中 尽量少删除数,使得被删之后的数组a的最大公约数比原来的大. 如果要删的数小于n,就输出要删的数的个 ...

  5. 22 Jquery 事件

    一.概述: 当用户与浏览器进行交互时这些方法被用于注册行为生效, 并进一步处理这些注册行为. 二.绑定事件处理器 .bind() ..unbind():为一个元素绑定一个事件处理程序.3.0版本已经弃 ...

  6. 请教一个问题关于JVM的,跪求大佬解答

    问题地址:https://blog.csdn.net/java_wxid/article/details/103021907

  7. Oracle RAC 服务启动流程

    启动流程步骤层次梳理:第一层:OHASD 启动: cssdagent - 负责启动 CSSD 的 Agent.orarootagent - 负责启动所有 root 用户下的 ohasd 资源 的Age ...

  8. hihoCoder 1785

    线性筛 + 递推 #include <bits/stdc++.h> , Mod = 1e9 + ; int n; int phi[N], prime[N], tot, ans; bool ...

  9. Cogs 2221. [SDOI2016 Round1] 数字配对(二分图)

    [SDOI2016 Round1] 数字配对 ★★★ 输入文件:menci_pair.in 输出文件:menci_pair.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述] 有 ...

  10. Input类中常用的验证方式

    Deolin一般将Input类对象作为POST请求方法的参数, Input类的域与前端的数据结构一一对应,由于后端不应该相信前端传过来的任何数据, 所以前端的数据对象先绑定到Input对象中,通过JS ...