单片机启动文件——数据段重定位,BSS段清零

目录

    • 重定位概念的引入
      • 一、数据段重定位
        • 1.作用:
        • 2.目的:
        • 3.自己模拟代码
      • 二、BSS段清零
        • 1.作用:
        • 2.目的:
        • 3.自己模拟代码
      • 三,实现原理

重定位概念的引入

单片机中内存段的详细介绍
在单片机中内存分为了很多不同的区域,在上面的文章中可以看到,flash与RAM中有两段空间的信息在flash与RAM都保持了,分别是RWdata段与bss段,在启动文件中对这两块区域分别进行了数据段重定位与BSS段清零,而对应的代码是由编译器根据散列文件自动生成的,我们看不到,但是我们可以不让编译器自动生成自己进行数据段重定位与BSS段清零

数据段重定位与BSS段清零对应的代码是由编译器根据散列文件自动生成的,我们看不到,我们可以通过反汇编文件以及Debug时的反汇编窗口看到编译器给我们生成的代码如何让keil编译生成bin文件与反汇编文件?,同时我们可以不让编译器自动生成自己进行数据段重定位与BSS段清零
操作方法就是
1.不使用main的函数名,使用其它函数名
在这里插入图片描述
在这里插入图片描述

一、数据段重定位

1.作用:
  • 将.data段从非易失性存储器(如Flash/ROM)复制到易失性存储器(RAM)中的目标位置。

  • 链接器在编译链接阶段,会将已初始化的全局变量和静态变量放入.data段,并将它们的初始值存储在Flash中。

  • 但是程序运行时,这些变量必须位于RAM中才能被修改。

  • 启动文件负责将存储在Flash中的初始值数据“搬运”到RAM中对应变量的地址处。

2.目的:
  • 确保初始化变量拥有正确的初始值:如果.data段没有从Flash复制到RAM,那么所有初始化为非零值的全局变量和静态变量在程序启动时将处于未定义状态(RAM上电后的值是随机的),而不是程序员设定的初始值。这会导致程序行为完全不可预测。

  • 满足C/C++语言规范要求:C/C++标准规定全局变量和静态变量必须在程序启动时完成初始化(如果有初始值)。重定位是实现这一语言要求的底层机制。

  • 实现变量的可写性:Flash通常是只读的(在运行时),而变量需要被程序读写。将初始值复制到RAM中是变量可写的先决条件。

3.自己模拟代码
/*启动文件模拟过程代码*/IMPORT |Image$$RW_IRAM1$$Base|IMPORT |Image$$RW_IRAM1$$Length|IMPORT |Load$$RW_IRAM1$$Base|LDR R0, = |Image$$RW_IRAM1$$Base|    ; DESTLDR R1, = |Load$$RW_IRAM1$$Base|     ; SORUCELDR R2, = |Image$$RW_IRAM1$$Length|  ; LENGTH //根据ARM架构AAPCS法则模拟函数参数BL My_Copy	 
/*C语言实现拷贝逻辑*/				 
void My_Copy(char* const Destination,char* const Soruce,int Size)
{int i = 0;for(;i < Size;i ++){Destination[i] = Soruce[i];}return;
}

二、BSS段清零

1.作用:
  • 将.bss段在RAM中对应的内存区域全部填充为0。

  • 链接器将未初始化或显式初始化为0的全局变量和静态变量放入.bss段。.bss段在程序映像(存储在Flash中)中不占用实际存储空间,它只记录需要在RAM中预留多少空间以及起始地址。

  • 启动代码需要找到.bss段在RAM中的起始地址和长度,然后将这块内存区域清零。

2.目的:
  • 确保未初始化的变量从0开始:C/C++标准规定未显式初始化的全局变量和静态变量在程序启动时必须被初始化为0(对于基本类型是0,对于指针是NULL)。如果不清零.bss段,这些变量在启动时将包含RAM上电后的随机垃圾值,导致程序行为不可预测,尤其是指针变量可能指向非法地址。

  • 节省Flash存储空间:由于.bss段中的变量初始值都是0,没有必要在Flash中存储一大串0值。启动时直接清零对应的RAM区域是更高效的方法(空间换时间)。

  • 满足语言规范要求:与.data段重定位一样,BSS清零是实现C/C++语言对未初始化/零初始化全局变量和静态变量初始化要求的底层机制。

3.自己模拟代码
/*启动文件模拟过程代码*/IMPORT |Image$$RW_IRAM1$$ZI$$Base|IMPORT |Image$$RW_IRAM1$$ZI$$Length|	LDR R0, = |Image$$RW_IRAM1$$ZI$$Base|   ; DESTLDR R1, = 0                             ; SORUCE LDR R2, = |Image$$RW_IRAM1$$ZI$$Length| ; LENGTH BL My_Zero_Init	//根据ARM架构AAPCS法则模拟函数参数BL My_Zero_Init
/*C语言实现清零逻辑*/				 
void My_Zero_Init(char* const Destination,int Soruce,int Size)
{int i = 0;for(;i < Size;i ++){Destination[i] = Soruce;}return;
}

三,实现原理

C语言-》编译器-》机器码(汇编就是机器码的注释)
展开能力,C语言与汇编的后沟就是编译器,C语言是编程工具,汇编语言是结果
判断结果是否符合预期?学会看反汇编
如何控制结果符合预期?学会一定的C语言语法以及编译器的工作特性

针对keil平台,控制编译器的方法就是分散加载文件
我们可以通过分散加载文件的语法来控制代码函数变量的链接地址
理论上也可以控制加载地址针对使用烧录器来说因为烧录器使用的是hex文件包含程序烧录的地址信息,但是一般来说程序编译后使用bin二进制文件这个文件使用特定的烧录工具,烧录的是纯机器码即代码指令不包含代码加载地址信息。
分散加载的语法可以参考分散加载文件与attribute关键字使用说明
同时分散加载文件中也包含一些符号信息,我们在代码中可以使用特定的语法来引入这些符号的值,RW-data段的加载地址大小,搬运的目的地址,同理bss段数据也是同理。
导入符号的方法有

/*汇编文件使用*/IMPORT |Image$$ER_IROM1$$Base|IMPORT |Image$$ER_IROM1$$Length|IMPORT |Load$$ER_IROM1$$Base|IMPORT |Image$$RW_IRAM1$$Base|IMPORT |Image$$RW_IRAM1$$Length|IMPORT |Load$$RW_IRAM1$$Base|IMPORT |Image$$RW_IRAM1$$ZI$$Base|IMPORT |Image$$RW_IRAM1$$ZI$$Length|	
/*C语言文件使用*/extern int Image$$ER_IROM1$$Base;extern int Image$$ER_IROM1$$Length;extern int Load$$ER_IROM1$$Base;extern int Image$$RW_IRAM1$$Base;extern int Image$$RW_IRAM1$$Length;extern int Load$$RW_IRAM1$$Base;extern int Image$$RW_IRAM1$$ZI$$Base;extern int Image$$RW_IRAM1$$ZI$$Length;	extern int Image$$ER_IROM1$$Base[];extern int Image$$ER_IROM1$$Length[];extern int Load$$ER_IROM1$$Base[];extern int Image$$RW_IRAM1$$Base[];extern int Image$$RW_IRAM1$$Length[];extern int Load$$RW_IRAM1$$Base[];extern int Image$$RW_IRAM1$$ZI$$Base[];extern int Image$$RW_IRAM1$$ZI$$Length[];	extern int * Image$$ER_IROM1$$Base;extern int * Image$$ER_IROM1$$Length;extern int * Load$$ER_IROM1$$Base;extern int * Image$$RW_IRAM1$$Base;extern int * Image$$RW_IRAM1$$Length;extern int * Load$$RW_IRAM1$$Base;extern int * Image$$RW_IRAM1$$ZI$$Base;extern int * Image$$RW_IRAM1$$ZI$$Length;	

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96501.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96501.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT(3)

四、基本组件1. Designer设计师&#xff08;掌握&#xff09;Qt Designer 是 Qt 提供的可视化界面设计工具&#xff0c;支持通过拖拽组件快速构建 GUI 界面&#xff0c;生成的界面文件以 .ui格式保存&#xff08;基于 XML 的标签语言&#xff09;。​​核心功能​​&#xff1a…

常用注解:@PostMapping、@RequestBody、@Autowired、@Service、@Mapper

1. PostMapping作用&#xff1a;将方法绑定到 HTTP POST 请求的特定路径上用法&#xff1a;PostMapping("/login") // 绑定到 POST /login PostMapping("/employees") // 绑定到 POST /employees PostMapping("/users/{id}") …

SoC日志管理

目录 一、汽车控制器中日志的核心类型 二、日志管理的核心环节与策略 1. 日志采集:确保“全面且不冗余” 2. 日志存储:平衡“可靠性”与“存储成本” 3. 日志安全:防止“篡改与泄露” 4. 日志生命周期:符合“法规与成本” 5. 日志工具与实现 三、汽车场景的特殊约束与应对 …

横评五款开源多智能体框架,AI高手都在用哪个?下一款Manus、Cursor、Devin,谁能撑起来?

Agent 成为共识的速度非常快。但今年 Agent 的真正转折点在于&#xff1a;多智能体。 从科研自动化到任务编排&#xff0c;从自动开淘宝店到 Vibe 一切&#xff0c;从 AI 浏览器到今天的 ChatGPT Agent&#xff0c;一切都是多智能体的味道。 但要真正搭建一个多智能体&#x…

GitHub每日最火火火项目(9.10)

1. Physical-Intelligence / openpi 项目名称&#xff1a;openpi项目介绍&#xff1a;基于 Python 开发&#xff0c;聚焦于物理智能领域&#xff0c;为相关研究与应用提供支持。Python 在科学计算、人工智能等领域有着广泛且成熟的生态&#xff0c;借助其丰富的库&#xff08;如…

2025年渗透测试面试题总结-61(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 2. 提交过什么漏洞 3. 常用漏洞扫描工具 4. OWASP TOP 10 2021核心变化 5. MySQL写WebShell权限要求 6.…

高可用消息队列线程池设计与实现:从源码解析到最佳实践

前言在现代分布式系统中&#xff0c;消息队列处理是核心组件之一。今天我们将深入解析一个高性能、高可用的消息队列线程池实现——FindMessageQueue&#xff0c;并探讨如何将其优化应用于实际项目中。一、核心架构设计1.1 整体架构图┌───────────────────…

Android App瘦身方法介绍

第一章 安装包构成深度剖析1.1 APK文件结构解剖APK文件本质是一个ZIP压缩包&#xff0c;通过unzip -l app.apk命令可查看其内部结构&#xff1a;Archive: app.apkLength Method Size Cmpr Date Time CRC-32 Name -------- ------ ------- ---- ---------- -…

深入浅出迁移学习:从理论到实践

1. 引言&#xff1a;为什么需要迁移学习&#xff1f;在深度学习爆发的这十年里&#xff0c;我们见证了模型性能的飞速提升 ——ResNet 在图像分类上突破人类视觉极限&#xff0c;BERT 在 NLP 任务上刷新基准&#xff0c;GPT 系列更是开启了大语言模型时代。但这些亮眼成果的背后…

嵌入式人别再瞎折腾了!这8个开源项目,解决按键/队列/物联网所有痛点,小白也能抄作业

嵌入式人别再瞎折腾了&#xff01;这8个开源项目&#xff0c;解决按键/队列/物联网所有痛点&#xff0c;小白也能抄作业 你是不是也有过这样的崩溃时刻&#xff1a;想做个按键控制&#xff0c;结果长按、连击、组合键的逻辑写了200行if-else&#xff0c;最后还时不时串键&#…

C++篇(7)string类的模拟实现

一、string的成员变量string和数据结构中的顺序表类似&#xff0c;本质上可以理解成字符顺序表&#xff0c;其成员变量仍然是_str&#xff0c;_size和_capacity。但是&#xff0c;C标准库里面也有一个string&#xff0c;和我们要自己实现的string类冲突了&#xff0c;该如何解决…

【直接套模板】如何用 Web of Science 精准检索文献?

在文献检索的时候遇到一些问题&#xff0c;单独使用关键词检索出来的文章数量太多&#xff0c;如果是多加一些限定词&#xff0c;又什么都检索不到&#xff1a;比如我明明知道某篇论文已经发表&#xff0c;但在 Web of Science (WoS) 里却检索不到。这其实和检索式的写法密切相…

HTTP 协议:从原理到应用的深度剖析

一、什么是HTTP协议&#xff1f;HTTP协议&#xff0c;全称 Hyper Text Transfer Protocol&#xff08;超⽂本传输协议&#xff09;的缩写&#xff0c;是⽤于服务器与客户端浏览器之间传输超⽂本数据&#xff08;⽂字、图⽚、视频、⾳频&#xff09;的应⽤层协议。它规定了客户端…

【算法--链表】138.随机链表的复制--通俗讲解

算法通俗讲解推荐阅读 【算法–链表】83.删除排序链表中的重复元素–通俗讲解 【算法–链表】删除排序链表中的重复元素 II–通俗讲解 【算法–链表】86.分割链表–通俗讲解 【算法】92.翻转链表Ⅱ–通俗讲解 【算法–链表】109.有序链表转换二叉搜索树–通俗讲解 【算法–链表…

为什么现在企业注重数据可视化?一文讲清可视化数据图表怎么做

目录 一、企业注重数据可视化的原因 1.提升数据理解效率 2.发现数据中的规律和趋势 3.促进企业内部沟通与协作 4.增强决策的科学性 5.提升企业竞争力 二、可视化数据图表的基本概念 1.常见的可视化图表类型 2.可视化图表的构成要素 3.可视化图表的设计原则 三、制作…

Cursor 辅助开发:快速搭建 Flask + Vue 全栈 Demo 的实战记录

Cursor 辅助开发&#xff1a;快速搭建 Flask Vue 全栈 Demo 的实战记录 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个…

实战:用 Python 搭建 MCP 服务 —— 模型上下文协议(Model Context Protocol)应用指南

&#x1f4cc; 实战&#xff1a;用 Python 搭建 MCP 服务 —— 模型上下文协议&#xff08;Model Context Protocol&#xff09;应用指南 标签&#xff1a;#MCP #AI工程化 #Python #LLM上下文管理 #Agent架构&#x1f3af; 引言&#xff1a;为什么需要 MCP&#xff1f; 在构建大…

宋红康 JVM 笔记 Day16|垃圾回收相关概念

一、今日视频区间 P154-P168 二、一句话总结 System.gc()的理解&#xff1b;内存溢出与内存泄漏&#xff1b;Stop The World;垃圾回收的并行与并发&#xff1b;安全点与安全区域&#xff1b;再谈引用&#xff1a;强引用&#xff1b;再谈引用&#xff1a;软引用&#xff1b;再谈…

OpenCV 高阶 图像金字塔 用法解析及案例实现

目录 一、什么是图像金字塔&#xff1f; 二、图像金字塔的核心作用 三、图像金字塔的核心操作&#xff1a;上下采样 3.1 向下采样&#xff08; pyrDown &#xff09;&#xff1a;从高分辨率到低分辨率 1&#xff09;原理与步骤 2&#xff09;关键注意事项 3&#xff09;…

【ARMv7】系统复位上电后的程序执行过程

引子&#xff1a;对于ARMv7-M系列SOC来说&#xff0c;上电后程序复位执行的过程相对来说比较简单&#xff0c;因为绝大部分芯片&#xff0c;都是XIP&#xff08;eXecute In Place&#xff0c;就地执行&#xff09;模式执行程序&#xff0c;不需要通过BooROM->PL(preloader)-…