2

正如标题所说,什么会占用 FLASH 中的更多空间(例如在 STM32 µC 中)?在函数内部声明全局变量还是声明静态变量?还是它们占用的空间相等?据我了解,这两个变量在程序的整个运行时都可用。只是他们的作用域不同。

4

3 回答 3

6

您可以有 0 初始化的全局和静态变量。这些通常不占用闪存,因为它们被放置在程序启动时分配并归零的内存位置,而不是来自闪存。

您也可以使用值初始化变量。在这种情况下,它们被放置在初始化的数据段中,因此根据数据类型的大小从闪存中占用空间。

您也可以使用代码初始化函数内的静态变量。该初始化必须在运行时发生,但只能发生一次,因此它实际上会生成更多代码,这几乎在任何情况下都会占用比数据大小更多的空间(不一定,至少如果您使用函数返回值)。main()您也可以对非常量全局变量执行几乎相同的操作,您只需将它们原地初始化为 0 并将赋值(例如)放在带到别处。

结论,全局和函数范围的静态变量都占用相同数量的空间。


上面假设嵌入式上下文中的“全局变量”,或作为文件范围的静态变量。如果它是在可动态链接的可执行文件中导出的全局符号,则该符号的重定位信息将在可执行二进制文件中占用一些空间。但是,我认为给定的示例系统不支持或使用可重定位的可执行文件。

于 2016-10-04T10:13:22.617 回答
2

正如标题所说,什么会占用 FLASH 中的更多空间(例如在 STM32 µC 中)?在函数内部声明全局变量还是声明静态变量?还是它们占用的空间相等?

使用 arm-none-eabi-gcc 作为 STM32 构建的参考,根本不占用任何闪存空间。

未声明的全局变量和静态变量如果需要启动初始化,则const进入该部分,如果不需要,则进入该部分。这两个段都由链接描述文件放入 SRAM。如果您正在使用 C++,那么静态 C++ 类最终会以..data.bss.bss

如果您确实声明了它们,const那么它们将被放置在该.rodata部分中,如果您查阅链接描述文件,您应该会发现它们位于.text闪存中的一个小节中。闪存通常比 SRAM 更丰富,因此请尽可能利用const

最后,优化器可以出现并完全重新排列它认为合适的任何东西,包括消除存储以支持内联。

于 2016-10-18T08:49:43.537 回答
2

“在整个运行时可用”的正式术语是静态存储持续时间。在文件范围(“全局”)声明的变量以及在两者中声明的所有变量static都具有静态存储持续时间。

因此范围和存储持续时间之间存在关系:范围可以决定变量获得的存储持续时间。但是范围和内存使用之间没有关系。

变量占用多少空间仅取决于该变量类型有多大。范围和存储时间与它无关。

在大多数编译器/链接器上,变量在闪存中结束通常需要两件事:

  • 它必须声明为const, 和
  • 它必须具有静态存储持续时间

如果不满足这些条件,则该变量将不会以 flash/nvm 结尾,无论它在哪个范围内声明。

于 2016-10-04T11:25:18.717 回答