【发布时间】:2020-08-28 05:18:47
【问题描述】:
我正在使用 Segger 嵌入式 Studio 为 Nordic NRF52840 微控制器编写嵌入式 C 代码。 编译我的代码后,我通过 gcc 获得了一个 .map 文件和一个 .hex 文件。
我想写一个脚本,它在.map 文件中寻找一个常量变量的地址。 然后,脚本应在 .hex 文件中搜索此地址,并通过从 .hex 文件中读取此地址处的值返回常量变量的值。
我的假设是,应该在微控制器的闪存中放置一个常量变量。因此,它应该存在于 .hex 文件中。为了找到这个变量的地址,我在 .map 文件中查找变量的名称。
但是现在,我的编译器/链接器有以下行为:
在我的代码中,我在主文件中定义了以下变量并保证链接器没有优化我的常量:
uint32_t const test123= 0x12345;
int main()
{
int retVal = foo_in_other_file();
if(test123 == retval)
{
static volatile int i = 0;
i++;
retval = true;
}
}
.map 文件中常量周围的部分如下所示:
.bss.is_asleeparr
0x0000000000000000 0x400 temp/release/main.o
.rodata.test123
0x0000000000000000 0x4 temp/release/main.o
.text 0x0000000000000000 0x0 temp/release/ble_advdata.o
.data 0x0000000000000000 0x0 temp/release/ble_advdata.o
.bss 0x0000000000000000 0x0 temp/release/ble_advdata.o
.text.sd_ble_gap_addr_get
常量变量test123 存在于.map 文件中,但为什么它的地址为零? 它是否被链接器优化掉了?
提前感谢您的帮助:)
编辑:
这是反汇编的截图。这是否意味着编译器确实将值解释为立即数并且它甚至没有存储到闪存中? 如果这是真的,我该如何避免这个?
【问题讨论】:
-
你能展示一下反汇编吗?编译器可能已将变量优化为指令的立即数,使其不会显式出现在内存中。此外,您可以使用
nm工具更轻松地找到符号的地址。您可以尝试将__attribute__((used))附加到变量。您还可以使用链接器脚本始终将变量放入同一地址,以避免每次都查找它。 -
@JörgWMittag 抱歉,“Flash”标签不正确
-
@Erlkoenig 我添加了我反汇编代码的图像。感谢您的建议,不幸的是“使用”属性并没有改变任何东西。链接描述文件的想法很好,但我不想有这个变量的固定地址。这会导致我的软件架构出现其他问题
-
根据你的截图(为什么不是文字?),值应该位于地址
0x2E6D2(=0xD*4+4+0x2E69A)。尝试使用nm工具而不是地图文件。我怀疑编译器将变量更改为文字池伪立即数,即程序内存中的值(而不是.rodata)。这可以解释为什么它不再显示为具有正确地址的实变量。也许__attribute__((used, section(".rodata")))有帮助。 -
@Erlkoenig 对不起截图。我不知道,屏幕截图在这里并不常见。我想,截图确实显示了我的 c 代码和汇编程序之间的联系。