8

有没有办法告诉 GCC 不要将特定的全局数组初始化为零?

我想保留一大块内存来存储我的代码管理的大型数据结构,所以我说:

#define SIZE_16_MB 0x01000000
BYTE mChunkSpace[SIZE_16_MB];

问题是 crtinit() 需要一百万年才能将这个空间初始化为零,而且根本没有必要。

有什么办法可以强制它不初始化那个空间?

目前我正在硬编码一个超出链接器所知的内存地址,但这不是一种特别强大的做事方式。

此外,这是一个缓慢的嵌入式 proc(50MHz Microblaze),所以不要假设我在谈论 PC。确实需要很长时间才能将该空间归零。

4

4 回答 4

8

您可以使用gcc属性将对象存储在另一个新的内存部分中,例如在.noinit内存部分中。

 BYTE mChunkSpace[SIZE_16_MB] __attribute__ ((section (".noinit")));
于 2012-06-24T20:37:34.560 回答
4

尝试动态初始化:

BYTE* mChunkSpace = (BYTE*)malloc(SIZE_16_MB * sizeof(BYTE));

然后这个数据是未初始化的,等待你初始化它。

于 2012-06-24T20:29:50.917 回答
2

您将在 SO 上获得的大多数答案都将倾向于 Visual Studio 或 GCC,无论是在通用平台(即 PC,无论是 Windows 还是 Linux)上,都将在“标准说......”引文中占据重要地位,这些都不适用于小型嵌入式系统,除非您碰巧正在运行嵌入式 Linux 或 Windows CE。

ouah 的答案可能最接近您的需要……如果您真正使用 GCC,也许正是您需要的。由于您想要的内存块非常大,可能会占用系统内存的大部分份额,因此最好的办法是在构建的链接器命令文件中定义一个特殊部分,或者通过 C、C++ 或汇编文件中的链接器指令定义. 这样做的语法因编译器而异。如果您在源/程序集文件中使用链接器指令,则可能需要指定有关内存区域的读/写能力等的属性……如果 Microblaze 没有 MMU/内存控制器,则可能不需要. 您需要在该部分的开头放置一个链接器符号,并在您的 C 代码中,使用“extern char symName[]”指令,这样你的 C 代码就可以在 reloc 中编译,链接器将用该节的实际地址覆盖。根据编译器和架构,您可能还需要使用某种“远”属性声明 symName[] extern;我对 Microblaze 的了解还不够,无法对此发表任何评论。

于 2012-06-24T20:58:52.553 回答
-1

该标准规定,在声明时未显式初始化的静态数据将被零初始化。您可以通过自己将第一个元素初始化为非零值来避免运行时初始化:

#define SIZE_16_MB 0x01000000
BYTE mChunkSpace[SIZE_16_MB] = {1};

请注意,如果您指定0,编译器可能只会将其存储在该.bss部分中,即,它仍将在运行时初始化。它不必这样做,但不这样做是愚蠢的。所以现在你的数组被扔进了这个.data段。

当然,这会使生成的可执行文件变得更大(确切地说是大约 16MB),但内存不会在运行时初始化。所以问题归结为什么对你很重要;将内存归零所需的时间,或生成的可执行文件大小?

于 2012-06-24T20:26:01.870 回答