ARM架构与编程——6.重定位的引入

文章介绍了STM32F103微控制器中程序的重定位过程,涉及到代码段、只读数据段、可读可写数据段(RAM)、BSS段(未初始化变量)的概念。重定位是指将程序从加载地址移动到链接地址的过程,确保程序正确运行。在Keil中,通过散列文件(.sct)进行配置,描述了加载域和执行域的布局,用于指导数据段的复制和BSS段的清零。文章还提供了如何在汇编和C语言中使用散列文件信息进行重定位的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于STM32F103的重定位

一、段的概念及重定位的引入

1.1 问题引入

在串口程序中添加全局变量,把它打印出来,看看会发生什么事。

char g_Char = 'A';
const char g_Char2 = 'B';	//const修饰的常量

//main()
putchar(g_Char);
putchar(g_Char2);

打印结果:
在这里插入图片描述
可以看到const修饰的常量和全局变量的地址空间并不一样,且变量 g_char 的值并不能打印出来,这是为什么呢?

我们先引入STM32F103的内存资源
在这里插入图片描述
可以看到g_char被保存到RAM中,而g_char2则被保存到ROM中
这是为什么呢?
RAM被称为随机存取存储器,而ROM则被成为只读存储器

因为RAM是可读可写的
ROM只可读,const修饰的是常量,只读就行,所以可以放在ROM里

所以在程序烧录的时候,.bin程序被烧写到ROM里面,变量g_char2的值就存储在ROM中,此时我们使用地址就可以访问到变量B;
而变量g_char存储在RAM里面,没人对他进行初始化操作,所以它的值就是一个随机值,打印出来就会变成乱码

为什么变量g_char的值会保存在RAM中呢,此时就需要我们引入重定位的概念。
什么是重定位呢?

烧写完程序,ROM上会有代码,变量的值等,所以在调用main函数之前,应该把数据复制到内存上去,这就是重定位(重新确定位置)

重定位为数据段重定位,代码重定位

  • 代码重定位

保存在ROM上的全局变量的值,在使用前要复制到内存,这就是数据段重定位。
代码直接放在ROM上运行即可,对于数据,可读可写的数据,我们需要把它从ROM上复制到RAM上去

  • 数据段重定位

想把代码移动到其他位置,这就是代码重定位。

在这里插入图片描述
接下来引入下一个问题:
访问可读可写的全局变量前,应该给它初始化一个值,谁来初始化?

在 start.s 启动文件里进行初始化

  • 段的详细解释

1.初始值放在ROM上,但是我们要去内存里访问它,所以在使用它前,我们需要把它的值从ROM上复制到内存里,像这类变量我们要把它们放在一块,这一段空间就称为可读可写的数据段.

2.像程序中的多个常量,我们也把它们放在一块,这一块空间就被成为只读数据段

3.指令本身,他们是属于代码段

4.对于初始值为0的变量,或者没有初始值的变量,假设有很多,我们需要把他们都保存到ROM上吗?
答案肯定是不用,对于这些变量,我们会把他们放在一块,这块空间就被称为BSS段,或者叫ZI段,使用前,只需把这段空间全部清零即可,相应的变量的值也就清零了

1.2 段的概念

代码段、只读数据段、可读可写的数据段、BSS段。

char g_Char = 'A';           // 可读可写,不能放在ROM上,应该放在RAM里
const char g_Char2 = 'B';    // 只读变量,可以放在ROM上
int g_A = 0;   // 初始值为0,干嘛浪费空间保存在ROM上?没必要
int g_B;       // 没有初始化,干嘛浪费空间保存在ROM上?没必要	放在BSS段上或者ZI段上

所以,程序分为这几个段:

  • 代码段(RO-CODE):就是程序本身,不会被修改
  • 可读可写的数据段(RW-DATA):有初始值的全局变量、静态变量,需要从ROM
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值