在内存管理的上下文中静态堆栈和动态堆栈之间有什么区别

时间:2015-07-24 06:21:01

标签: memory-management dynamic static stack

  1. 静态存储区域的大小在整个执行过程中是不变的,但动态堆栈会根据激活记录的推送和弹出而增长和缩小。
  2. 在静态堆栈中执行之前已知的存储要求但是int动态堆栈堆栈帧的大小和结构在编译时是已知的,但实际内容和分配时间在运行时之前是未知的。
  3. 还有什么可以是差异,任何人都可以帮助我使用代码段。 谢谢。

1 个答案:

答案 0 :(得分:1)

由于我目前正在使用一种静态堆栈的系统上工作,所以我可以在这里稍作介绍。

由于您提到了堆栈框架,因此在输入较深的嵌套子例程时,必须知道堆栈用于跟踪上下文。只是在下一段中明确提到了此b / c。

通常,堆栈和堆被视为动态的[em> ,这意味着它们可以扩展大小-通常通过malloc()等行的内存管理来完成。{{3} }。如您在中间面板中所见,堆栈只能以井井有条的方式增长和收缩,因为只能在底部边缘分配或释放内存。另一方面,堆可以看到内部任何地方分配/释放的内存。当两个区域相遇时将发生冲突-这将引起一个大问题,因为无法调用其他子例程。此外,很难预测何时会发生这种情况。

如果要避免此类问题(例如,在安全性至关重要的应用程序中),则可以选择不允许在堆栈+堆中的一个或两个中使用动态内存。使用静态堆栈的好时机是当您确信程序不会超过子例程调用的特定深度时(例如,不进行递归,或限制递归)。使用静态堆栈还可以简化实现,这是您在裸机应用程序中可能要考虑的问题。

以下代码是如何在启动代码中实现静态堆栈的一个小示例:

//*****************************************************************************
//
// Reserve space for the system stack.
//
//*****************************************************************************
__attribute__ ((section(".stack")))
static uint32_t g_pui32Stack[1024];

section属性允许您使用链接描述文件在内存中定位堆栈:

ENTRY(Reset_Handler)

MEMORY
{
    FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K
    SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K
}

SECTIONS
{
    .text :
    {
        /* This is where executable code gets stored */
    } > FLASH

    /* User stack section initialized by startup code. */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        *(.stack)
        *(.stack*)
        . = ALIGN(8);
    } > SRAM

    .data :
    {
        /* This is where global/static initialized variables are stored */
    } > SRAM AT>FLASH

    .bss :
    {
        /* This is where global/static 0-filled variables are stored */
    } > SRAM

    .heap (COPY):
    {
        /* This is where dynamically allocated storage could be used */
    } > SRAM
}

您会发现在这种情况下,堆栈并不位于堆旁边。可以将静态堆栈放置在所需的任何位置,因为假设您永远不会超出堆栈的边界。