You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中获取LD链接脚本定义的变量值(裸机场景)

从LD链接脚本获取地址变量到C代码的正确方式

你的实现思路方向是对的,但C代码里的符号声明和使用存在关键错误,会导致你拿不到期望的地址值,我来帮你修正并解释清楚:

问题核心

链接脚本里的PROVIDE(__START_OF_PROG_MEMORY = .);是把当前链接地址(这里是0x80000)赋值给这个符号——注意,这个符号本质是一个数值常量,它不占用任何实际内存空间,只是链接器记录的一个地址标记。

但你在C里的声明是:

extern unsigned long* __START_OF_PROG_MEMORY;

这会让编译器误以为__START_OF_PROG_MEMORY是一个占用内存的指针变量,而非你想要的地址常量。之后你又用&__START_OF_PROG_MEMORY取它的地址,这得到的是这个符号在内存中的位置(如果存在的话),完全不是你期望的0x80000。

正确实现方式

修正后的C代码

把符号声明成普通的unsigned long类型(因为它是一个地址数值),直接将其值转换成指针即可:

// 声明链接脚本提供的地址常量
extern unsigned long __START_OF_PROG_MEMORY;
// 用常量值直接作为指针地址
volatile unsigned long *StartOfProgram = (volatile unsigned long *)__START_OF_PROG_MEMORY;

链接脚本的合理性

你的链接脚本本身是符合裸机程序规范的:

  • . = 0x80000;设定程序起始地址后立刻PROVIDE符号,确保它准确对应程序的起始位置
  • 各个段(.text、.rodata、.data、.bss)的定义符合裸机程序的常规写法,NOLOAD和ALIGN的使用也正确
  • __bss_size的计算:如果你的目标架构中unsigned long是8字节,>>3(等价于除以8)能正确得到bss段的元素数量;如果是4字节,需要改成>>2,这点可根据你的目标架构调整。

验证小技巧

链接完成后,你可以用nm工具查看符号表,确认__START_OF_PROG_MEMORY的值是否为0x80000:

nm your_program.elf | grep __START_OF_PROG_MEMORY

正常输出应该类似00080000 D __START_OF_PROG_MEMORY(D表示已初始化数据,这里实际是链接器提供的常量)。

内容的提问来源于stack exchange,提问作者Oliver Strong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:13:06