C 防止使用(从优化的副本)数据段到本地堆栈数据结构/阵列
我正在编写一些固件,需要在不使用数据段的情况下使用C代码。假设一个人远离地球人,这是非常简单的。至少我是这么想的 我编写了一些功能类似于以下代码的代码:C 防止使用(从优化的副本)数据段到本地堆栈数据结构/阵列,c,gcc,optimization,embedded,C,Gcc,Optimization,Embedded,我正在编写一些固件,需要在不使用数据段的情况下使用C代码。假设一个人远离地球人,这是非常简单的。至少我是这么想的 我编写了一些功能类似于以下代码的代码: void func() { int feature_set[][2] = { {feature0, 1}, {feature1, 0}, {feature2, 0} }; //Use 'feature_set' for some hardware init } 在我的特
void func()
{
int feature_set[][2] = {
{feature0, 1},
{feature1, 0},
{feature2, 0}
};
//Use 'feature_set' for some hardware init
}
在我的特定用例中,feature\u set
指的是我需要用于初始化的一些配置数据。因为我是在堆栈上创建这个数据集的,所以我希望在使用之前在堆栈上构造它。我意识到这会产生更多的指令,但在这种情况下,这是一个我可以接受的权衡
然而,在查看拆解后,我意识到它实际上是在做这样的事情:
mov ecx, <size>
lea edi, <stack addr>
lea esi, <somewhere in .data>
rep movs
mov-ecx,
lea edi,
李埃西,
雷普莫夫斯
很明显,编译器试图通过在.data
中创建结构的常量版本并在需要时将其复制到堆栈来优化此操作
问题是:有没有办法防止这种情况?有没有办法告诉编译器不要将数据段用于此操作?更改优化级别可能会奏效,但我确实希望进行优化工作。。。只是没有特别针对这种构造 初始值设定项列表必须存储在某个地方,您不能在稀薄的空气中分配它。通常初始值设定项列表位于
.text
/.rodata
中。然后,编译器可以通过将功能集
放在.data
而不是堆栈中来优化初始化,以更快地初始化它
无论如何,您可以这样做:
static const uint32_t FEATURE_SET [][2] =
{
{feature0, 1},
{feature1, 0},
{feature2, 0}
};
现在,阵列应该放在闪存中(.rodata
或类似),否则链接器设置中的某些内容会出错
然后,如果需要堆栈上可修改的运行时版本:
uint32_t feature_set [ sizeof(FEATURE_SET) / sizeof(*FEATURE_SET) ] [2];
memcpy(feature_set, FEATURE_SET, sizeof feature_set);
另外,请确保不要使用奇怪的RAM调试版本,而是始终将程序下载到闪存,无论是调试版本还是发布版本。如果您是在嵌入式系统上,您的编译器可能会有一些pre-proseesor指令,您可以使用它们来说明应该位于何处。如果这是用于闪存的固件,我将通过使用段属性或其他方式明确指示链接器,将只读数据放入flash中。哦,当然,让它成为
const
,也许这就是所需要的。什么是特性0等等?编译时常量还是运行时变量?@Lundin,整个数组是由常量构成的。这种情况下,我只有一个text
部分。我的希望是,我可以不使用静态“初始值设定项”,让GCC输出更多的指令,在函数enter(即,常量移到堆栈上)时进行初始化。GCC与-O0
的默认行为正是这样,但在项目I的其他地方是-Os
或-O3
。我发现我可以在文件范围内推送-O0
选项(或者只包装函数),这也可以工作。我想这是可以的,但是让函数的行为完全依赖于优化级别并不是一个好的设计。也许我以后会的。这是一个爱好项目。