ZHCU875Z August 2001 – October 2023 SM320F28335-EP
当您在 C/C++ 中声明 int x = 1234;
等变量时,系统将在地址 &x 处创建标识符(名称)为“x”且内容为 1234 的对象。此外,系统还会创建一个名为 x
的相关链接器符号。该链接器符号仅表示地址,而不是对象本身。引用链接器符号 x
会得到链接器符号的值,即地址。但是,对 C/C++ 标识符 x
的引用会得到内容 1234。如果您需要此 C/C++ 标识符的地址,则需要使用 &x
。因此,C/C++ 表达式 &x
与链接器表达式 x
具有相同的值,单链接器符号没有关联类型。
假设链接器定义的符号表示整数而不是地址,例如 __TI_STACK_SIZE。无法在编译器中直接引用整数链接器符号,因此我们使用了一个技巧。首先,假设此链接器符号代表一个地址。在 C/C++ 代码中声明名称相同的假变量。现在,请参考 &__TI_STACK_SIZE,这是一个与链接器符号 __TI_STACK_SIZE 具有相同值的表达式。该值的类型不正确,您可以通过转换更改该类型,如下所示:
extern unsigned char __TI_STACK_SIZE;
size_t stack_size = (size_t) &__TI_STACK_SIZE;
如以上示例所示,省略 _symval 在大部分时间中都会起作用,但并非总是如此。在某些情况下,指针值不足以表示链接器符号值。例如,一些目标具有 16 位地址空间,因此为 16 位指针。TI 链接器符号为 32 位,因此链接器符号的值可大于可由目标指针表示的值。在这种情况下,表达式 &v 仅反映链接器符号“v”实际值的较低 16 位。要解决此问题,请使用内置的 _symval 运算符,它会复制链接器符号的所有值位:
extern void v;
unsigned long value = (unsigned long)_symval(&v);
对于每种链接器符号,请使用此模式:
extern void name;
desired_type name = (desired_type)_symval(&name);
例如,
extern void farfunc;
void foo()
{
void (*func)(void) = (void (*)(void))_symval(&farfunc);
func();
}