【发布时间】:2015-07-29 12:53:02
【问题描述】:
我的问题是非常基本的。我正在用汇编程序制作我的第一个裸机程序。架构是 ARMv7-M,我使用的是 GNU,我正在用 UAL 编写代码。
我在.bss(或.data,没关系)中有一个变量声明如下:
.lcomm a_variable, 4
然后我想在程序的某个地方读取它的值。为此,我首先将其地址加载到寄存器中,然后将变量本身的值加载到另一个寄存器中:
adr r0, a_variable
ldr r1, [r0, #0]
到目前为止一切顺利。编译后的对象包含我的 a_variable 符号:
00000000 b a_variable
生成的指令如下所示:
0: f2af 0004 subw r0, pc, #4
4: 6801 ldr r1, [r0, #0]
问题始于我想将对象链接到生成的图像中。 ld 将 a_variable 符号重新定位到新地址的最终 .bss 部分:
20001074 b a_variable
但最终代码保持不变,程序确实尝试从地址 0x0 而非 0x20001074 读取 a_variable。
我希望 ld 以某种方式替换新地址,因为当您链接由 GCC 编译的对象时,它似乎会这样做。我的意思是,如果我写一段 C 代码做类似的事情:
static int a_variable;
void foo(void)
{
a_variable = 5;
}
...然后我在目标文件中得到以下说明:
0: f240 0300 movw r3, #0
4: f2c0 0300 movt r3, #0
8: 2005 movs r0, #5
a: 6018 str r0, [r3, #0]
...但最终的图像看起来像这样:
800c: f242 338c movw r3, #9100 ; 0x238c
8010: f2c0 0301 movt r3, #1
8014: 2005 movs r0, #5
8016: 6018 str r0, [r3, #0]
So ld 似乎用真实地址代替了左边的占位符。
我的问题是为什么这在手写汇编代码的情况下不起作用?我错过了什么?
【问题讨论】:
-
ADR 指令仅适用于同一节中的标签。汇编器或链接器应该产生了错误。
-
嗯,它没有。可能是因为a_variable和adr指令在联动之前距离不是很远(其实都是同一个0地址)?
-
我认为这只是一个错误。汇编器在 ARM 模式下给出错误:
Error: symbol .bss is in a different section。您的代码是否需要与位置无关? -
我猜没有。这只是我只想在我的 stm32f4 MCU 上运行的应用程序。
标签: assembly gnu armv7 binutils