如何通过宏向ARM链接器传递地址以指定变量存储位置
解决ARM编译器6通过宏定义指定变量存储地址的问题
ARM编译器6不再支持__attribute__((at())),改用__attribute__((section(".ARM.__at_<地址>")))来指定变量地址,但直接在section字符串中使用宏名会导致链接错误——原因是预处理器不会解析字符串常量内部的宏标识,所以.ARM.__at_ADDR里的ADDR不会被替换为实际地址,链接器无法识别该section的基地址。
可行的解决方法是利用预处理器的字符串化与宏展开特性,通过两层宏实现地址的动态替换:
方法实现
// 第一层宏:将参数转换为字符串 #define STRINGIFY(x) #x // 第二层宏:先展开地址宏,再字符串化,生成合法的section属性 #define AT_ADDR(addr) __attribute__((section(".ARM.__at_" STRINGIFY(addr)))) // 定义目标地址宏 #define ADDR 0x20000000 // 使用宏指定变量地址 int var AT_ADDR(ADDR);
原理说明
- 调用
AT_ADDR(ADDR)时,预处理器先将ADDR展开为0x20000000; STRINGIFY(0x20000000)把数值转换为字符串"0x20000000";- 最终拼接生成的属性为
__attribute__((section(".ARM.__at_0x20000000"))),和直接写地址的效果完全一致。
简洁替代写法
也可以合并为一个宏(利用预处理器展开顺序实现):
#define AT_ADDR(addr) __attribute__((section(".ARM.__at_" #addr))) #define ADDR 0x20000000 // 额外加一层宏确保ADDR被正确展开 #define DEFINE_VAR_AT_ADDR(var_name) int var_name AT_ADDR(ADDR) DEFINE_VAR_AT_ADDR(var);
相对来说,两层宏的写法可读性更强,更推荐使用。
内容的提问来源于stack exchange,提问作者AlphaGoku
相关产品推荐
相关产品推荐

