编译与链接的本质:段(Section)的生成与定位

1. 编译阶段:分类与生成

  • 输入:源代码(C/C++/汇编等)
  • 处理 :编译器根据变量/函数的属性(是否初始化、是否用 __attribute__((section("name"))) 修饰等)将内容归类到不同的段(Section)。
  • 输出 :目标文件(.o.obj),其中每个段内仅包含相对于该段起始的偏移地址最终运行时地址尚未确定

2. 链接阶段:定位与整合

  • 输入 :多个目标文件 + 链接脚本.ld
  • 处理
    1. 收集所有目标文件中的同名段,合并成一个大的段。
    2. 按照链接脚本的规则,为每个段分配最终的运行时地址 (在裸机/固件环境下即物理地址)。
    3. 修正代码中的地址引用(重定位),生成可执行映像。
  • 输出 :可执行映像文件(如 .elf.bin.hex

3. 自定义段的工作机制

  • 在代码中定义 :使用编译器扩展(如 GCC 的 __attribute__((section("my_section"))))将特定变量或函数放入自定义段。

  • 在链接脚本中声明:必须显式描述如何处理该自定义段,例如:

    my_section : { *(.my_section) } > RAM

否则,该段会被链接器丢弃,不会出现在最终内存映像中。

4. 核心总结

编译负责"分类",链接负责"定位"

链接脚本是连接编译输出与最终内存布局的蓝图

自定义段通过编译属性生成,再通过链接脚本精确落地到特定内存地址,这是固件开发中实现精细内存控制(如调试缓冲、DMA 区域、保留内存)的根本方法。


注:上述机制适用于裸机/固件环境(无操作系统加载器介入)。在有操作系统的环境中,链接脚本生成的为相对地址,最终由操作系统加载器完成虚拟地址映射。

相关推荐
zlinear数据采集卡3 分钟前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Flittly17 分钟前
【雕虫大技】Agent 动态 Skill 供应链安全加固(三):输出校验与治理闭环实战
java·spring boot·spring
Poo_Chai17 分钟前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库
瑞码空间24 分钟前
Java 图形界面(GUI)完整知识点手册
java·开发语言·图形界面·swing
茶本无香1 小时前
Java调用Shell脚本执行SQL数据库操作:从入门到实战
java·sql·shell
小努蛋1 小时前
linux编译openresty异常问题,lua_cjson.c:706:5: 错误: ‘for‘ 循环初始化声明只在 C99 或 C++ 模式下允许
开发语言·lua·openresty
风流 少年1 小时前
Spring AI 2.0:MCP
java·后端·spring
qz_Serene1 小时前
C++:类和对象(上)
开发语言·c++
小绫网络安全1 小时前
Kali Linux渗透测试入门教程:从零搭建到实战攻防
linux·运维·服务器