0

0

C++的Linker Script怎么写_定制C++程序内存布局与段管理的链接器脚本

冰火之心

冰火之心

发布时间:2025-12-05 09:45:07

|

548人浏览过

|

来源于php中文网

原创

链接器脚本可精确控制C++程序内存布局,通过MEMORY定义内存区域,SECTIONS映射段到指定地址,支持自定义段如.fastcode、符号定义如\_sbss/\_ebss用于BSS清零,结合ENTRY设置入口点,并在构建时用-T选项指定脚本,适用于嵌入式系统或内核开发中对内存和性能的精细控制。

c++的linker script怎么写_定制c++程序内存布局与段管理的链接器脚本

编写 C++ 程序的链接器脚本(Linker Script)可以精确控制可执行文件的内存布局、段(section)排列和符号地址。这在嵌入式系统、操作系统内核开发或对性能与内存有严格要求的场景中非常有用。GNU ld 使用的链接器脚本语法灵活,能定义内存区域、段映射和输出节布局。

理解链接器脚本的作用

默认情况下,编译器和链接器会使用内置规则安排代码、数据、只读数据等放入标准段(如 .text.data.bss)。但当你需要:

  • 将某些函数放到特定内存区域(如高速 SRAM)
  • 分离调试信息或自定义段
  • 为多核处理器分配不同核心使用的内存区
  • 实现位置无关代码或固定加载地址

就需要手动编写链接器脚本。

立即学习C++免费学习笔记(深入)”;

基本语法结构

一个典型的链接器脚本由以下几个部分组成:

  • MEMORY:定义可用内存区域及其属性
  • SECTIONS:指定各个输入段如何映射到输出段,并设置其位置和对齐方式
  • 可选地定义符号(如堆起始地址)

示例:简单嵌入式系统的链接脚本

/* 定义物理内存布局 */
MEMORY
{
    FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
    RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 128K
}

/ 设置入口点 / ENTRY(Reset_Handler)

/ 描述段如何分布 / SECTIONS { / 向量表放在 Flash 起始位置 / .vectors : { KEEP(*(.vectors)) } > FLASH

/* 代码段 */
.text : 
{
    *(.text)
    *(.rodata)
} > FLASH

/* 初始化过的全局变量 — 运行时从 Flash 复制到 RAM */
.data : 
{
    _sdata = .;
    *(.data)
    _edata = .;
} > RAM AT > FLASH

/* 未初始化变量放在 RAM */
.bss :
{
    _sbss = .;
    *(.bss)
    *(COMMON)
    _ebss = .;
} > RAM

/* 堆和栈预留空间(可通过符号供 C 代码使用) */
_end = .;
PROVIDE(__stack_start__ = ORIGIN(RAM) + LENGTH(RAM));

}

在 C++ 中使用自定义段

C++ 允许你将函数或变量放入自定义段,然后在链接脚本中处理它们。

例如,把关键函数放入高速内存:

北极象沉浸式AI翻译
北极象沉浸式AI翻译

免费的北极象沉浸式AI翻译 - 带您走进沉浸式AI的双语对照体验

下载
// C++ 代码中指定段
void __attribute__((section(".fastcode"))) fast_math()
{
    // 高频调用函数
}

对应链接脚本添加对该段的支持:

SECTIONS
{
    .fastcode (NOLOAD) :
    {
        *(.fastcode)
    } > RAM
}

这里 (NOLOAD) 表示该段不需从 Flash 加载初始化内容(适用于纯运行时代码),但如果要从 Flash 拷贝,则类似 .data 的方式使用 AT>

控制符号与对齐

链接器脚本可用于定义虚拟符号,用于标记边界或传递信息给程序。

.bss :
{
    . = ALIGN(4);
    _sbss = .;
    *(.bss)
    . = ALIGN(4);
    _ebss = .;
} > RAM

这些符号可在 C++ 中声明并使用:

extern "C" {
    extern char _sbss, _ebss;
}

void clear_bss() { for (char p = &_sbss; p < &_ebss; ++p) p = 0; }

注意:符号是地址,取地址时加 & 符合惯例。

与构建系统集成

使用链接器脚本需告诉 g++/ld 使用它:

g++ -T myscript.ld main.cpp -o program.elf

在 Makefile 或 CMake 中配置:

# Makefile 示例
LDFLAGS += -T myscript.ld

CMake 示例

target_link_options(myapp PRIVATE -T${CMAKE_CURRENT_SOURCE_DIR}/myscript.ld)

确保脚本路径正确,且没有与其他标准启动文件冲突(如 crt0.o 等)。

基本上就这些。通过合理设计链接器脚本,你可以完全掌控 C++ 程序的内存布局,优化启动流程、运行效率和资源利用。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

linux是嵌入式系统吗
linux是嵌入式系统吗

linux是嵌入式系统,是一种用途广泛的系统软件,其特点是:1、linux系统是完全开放、免费的;2、linux操作系统的显著优势是多用户和多任务,保证了多个用户使用互不影响;3、设备是独立的,只要安装驱动程序,任何用户都可以对任意设备进行使用和操作。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

170

2024.02.23

C++ 嵌入式系统开发入门与实践
C++ 嵌入式系统开发入门与实践

本专题将带你系统掌握 C++ 在嵌入式系统中的实战应用,内容覆盖硬件抽象、驱动开发、内存与性能优化、实时系统编程、跨平台编译构建,以及常用嵌入式框架与调试技巧,帮助开发者从零构建可运行于 MCU、ARM 等平台的高性能嵌入式项目。

209

2025.11.18

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

2

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

39

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

101

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7万人学习

C 教程
C 教程

共75课时 | 4.1万人学习

C++教程
C++教程

共115课时 | 12.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号