11

由于我对 C 比较陌生,因此我必须为我的项目之一使用以下内容:我必须声明一些全局变量,每次程序在相同的内存地址运行时都必须存储这些变量。我做了一些阅读,我发现我将它声明为“静态”,它将存储在同一个内存位置。

但我的问题是:我能否指出程序在哪里存储该变量。例如:int a 要存储在 0xff520000。这件事能不能做?我在这里搜索过,但没有找到任何相关的例子。如果他们是关于此的一些旧帖子,请分享链接。

谢谢大家。劳伦蒂乌

更新:我使用的是 32uC

4

8 回答 8

12

在您的 IDE 中,将通过一些链接器文件提供内存映射。它将包含程序中的所有地址。阅读 MCU 手册以查看哪些地址有有效的内存供您使用,然后为您的变量保留一些内存。您必须阅读特定开发平台的文档。

接下来,请注意,将变量映射到特定地址没有多大意义,除非它们是硬件寄存器或驻留在闪存或 EEPROM 中的非易失性变量。

如果这样一个内存位置的内容在执行期间会发生变化,因为它是一个寄存器,或者因为您的程序包含更改 NVM 存储单元的引导加载程序/NVM 编程算法,则必须将变量声明为易失性。否则编译器会在优化时完全破坏你的代码。

特定的编译器很可能有一种非标准的方式来在特定地址分配变量,例如 #pragma 或有时是奇怪的非标准@运算符。您可以在标准 C 中的固定位置分配变量的唯一明智方法是:

#define MY_REGISTER (*(volatile uint8_t*)0x12345678u)

其中 0x12345678 是其中 1 个字节所在的地址。一旦你有了这样的宏声明,你就可以像使用变量一样使用它:

void func (void)
{
  MY_REGISTER = 1;  // write
  int var = MY_REGISTER;  // read
}

大多数情况下,您希望这些变量驻留在全局命名空间中,因此是宏。但是,如果您出于某种原因希望缩小变量的范围,请跳过宏并在代码中手动访问地址:

void func (void)
{
  *(volatile uint8_t*)0x12345678u = 1; // write
  int var = *(volatile uint8_t*)0x12345678u; // read
}
于 2013-03-07T10:32:36.940 回答
8

您可以使用链接器脚本来做这种事情,这在嵌入式编程中很常见。

在 Linux 系统上,由于地址空间随机化,您可能永远不会获得相同的虚拟地址(一种安全功能,可避免依赖于了解您所描述的变量的确切位置的漏洞利用)。

如果它只是您想要的可重复指针,您可以使用 映射特定地址mmap,但这不能保证。

于 2013-03-07T09:11:38.553 回答
2

就像其他答案中提到的那样 - 你不能。但是,您可以有一个解决方法。如果可以在 中初始化全局变量,则main()可以执行以下操作:

int addr = 0xff520000;

int main()
{
    *((int*)addr) = 42;
    ...
    return 0;
}

但是请注意,这非常依赖于您的系统,如果在受保护的环境中运行,您很可能会遇到运行时崩溃。如果您在嵌入式/不受保护的环境中,这可以工作。

于 2013-03-07T09:16:44.843 回答
1

不,您不能明确告诉它在内存中存储变量的位置。主要是因为在现代系统上,系统在内存方面做了很多事情,这是你无法控制的。地址布局随机化是一件让这变得非常困难的事情。

于 2013-03-07T09:10:19.313 回答
1

如果您使用 XC8 编译器,请根据您的编译器。你可以简单地写 int x @ 0x12 ;

在这一行中,您在内存位置 0x12 中设置 x

于 2020-10-07T14:17:11.027 回答
0

您可以声明一个指向特定内存地址的指针,并将该指针的内容用作我想的变量:

int* myIntPointer = 0xff520000;
于 2013-03-07T09:16:07.187 回答
0

不在C级。如果使用汇编语言,则可以直接控制内存布局。但是 C 编译器会为您执行此操作。你真的不能乱来。

即使使用汇编,这也只能控制相对布局。虚拟内存可以将其放置在任何(不)方便的物理位置。

于 2013-03-07T09:10:46.927 回答
0

您可以使用一些编译器扩展来做到这一点,但这可能不是您想要做的。操作系统会处理你的记忆,并将东西放在它想要的地方。你怎么知道你想要的内存地址会映射到你的程序中呢?如果您在嵌入式平台上,请忽略本段中的所有内容,那么您应该阅读该平台/编译器的手册,或者至少在此处提及它,以便人们可以给出更具体的答案。

此外,静态变量在程序运行时不一定具有相同的地址。许多操作系统使用与位置无关的可执行文件,并在每次执行时随机化地址空间。

于 2013-03-07T09:14:26.587 回答