ZHCUAU3J January 2018 – March 2024
当您在 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 链接器符号为 64 位,因此链接器符号的值可大于可由目标指针表示的值。在这种情况下,表达式 &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();
}
在 C7000 器件上,表示整数或出于其他某种原因而不表示有效地址的链接器符号不能始终用指针值表示。在此类情况下使用 _symval 以确保获得正确的值。