2

所以我正在阅读 MicroC/OS-II 的书,但是在任务堆栈部分我找不到确切的堆栈是什么,最重要的是 - 它的用途是什么。我知道这不是一件漫长而困难的事情,但我有点'必须理解它。这本书只说如何设置堆栈大小和其他一些类似的东西。那么,有人可以用简短的语言解释一下 uC/OS-II 中的任务堆栈是什么以及它的用途是什么?

4

4 回答 4

5

一般来说,在过程编程语言的上下文中,堆栈是存储函数/过程/子例程的局部变量和返回地址的地方(在“堆栈帧”中)——调用深度越大,堆栈帧就越多存储 - 每个尚未返回的函数一个。无论您是否使用诸如 MicroC/OS-II 之类的 RTOS,这部分都是正确的。

在单线程环境中,只需要一个堆栈,这通常作为 C 运行时环境设置的一部分提供给您。在多线程环境中,每个单独的执行线程都需要一个堆栈,并且通常由您为每个线程分配堆栈空间,或者至少指定其长度。

于 2013-05-29T11:53:54.813 回答
3

我不知道 MicroC/OS-II,但任务的堆栈几乎总是相同的:
在任务执行期间,它存储当前上下文所需的数据。这意味着当调用子程序(方法等)时,堆栈顶部会存储一个“堆栈帧”。该堆栈帧存储被调用子程序的局部变量、子程序完成时使用的返回地址以及其他一些信息。当子程序返回时,堆栈帧被删除。如果子例程调用另一个(或递归地),另一个堆栈帧存储在当前堆栈的顶部。
与堆栈中存储的数据以与存储数据相反的顺序删除相反,堆存储数据只要它们的内存没有被释放,这可以以任意顺序完成。

于 2013-05-29T10:12:23.607 回答
3

许多处理器都有一个堆栈指针,其中大多数都有专门使用该堆栈指针的指令。堆栈指针是一个保存地址的寄存器,与程序计数器不同。堆栈只是堆栈指针指向的内存,在更高级别上,您或操作系统或某人将可用内存空间划分为不同的用途,一点点用于数据,一点点用于程序,一点点用于堆(mallocs 和 frees)还有一些用于堆栈。堆栈指针和相关指令允许代码临时分配一些内存。例如,一个全局变量至少在您的程序的生命周期内卡在一个内存位置。一个局部变量虽然只需要一个内存位置,而函数正在执行,当函数返回时,您不需要该局部变量内存(静态定义的局部变量像全局变量一样分配,但仅在该函数期间可用,因此不是临时的)。您可以在函数中执行 malloc 和 free 来分配此本地内存,或者您可以简单地使用堆栈。许多/大多数编译器只是使用堆栈。除了局部变量,您可能还需要存储返回地址,如果函数 a() 调用函数 b() 以从 b 回到您在 a 中的位置,则您需要在调用 b() 后返回到下一条指令. 如果 B 调用 c,那么在 b() 的上下文中,您需要将返回值保存到 a(),现在在 c() 中,您需要知道如何返回到 b()。等等。这取决于架构和调用约定,一些架构总是使用堆栈来返回,有些人倾向于使用特定的寄存器。当嵌套调用时,尽管所有架构最终都需要使用堆栈作为返回地址,所以这里也使用堆栈。如果函数 a() 调用自身 10 次并且有一个本地整数并且返回地址可以说它每次调用需要 8 个字节的堆栈,所以第一次调用将堆栈指针移动 8 个字节分配 8 个字节,第二次调用另一个 8 个等等. 当你开始点击返回时,堆栈指针向后移动 8 个字节,另一个返回另一个堆栈指针上的 8 个字节。所以第一次调用将堆栈指针移动 8 个字节,分配 8 个字节,第二次调用另一个 8 个字节,依此类推。当你开始点击返回时,堆栈指针向后移动 8 个字节,另一个返回另一个堆栈指针上的 8 个字节。所以第一次调用将堆栈指针移动 8 个字节,分配 8 个字节,第二次调用另一个 8 个字节,依此类推。当你开始点击返回时,堆栈指针向后移动 8 个字节,另一个返回另一个堆栈指针上的 8 个字节。

现在,如果为每个应用程序/任务/过程/线程/任何您可能希望它们中的每一个拥有自己的堆栈的东西同时执行(操作系统),则将其从单个应用程序转换为具有错觉的多个应用程序。这通常很容易,因为您只需要保存前一个任务的堆栈指针,并将堆栈指针设置为下一个任务切换时的最后一个值。当然,您可以变得更加复杂并拥有保护机制,因此每个应用程序只能存在于其内存空间中,包括堆栈和堆。mmus 可以通过将物理内存分成许多块来使其变得更加复杂,并且 mmu 使它看起来像单独的块在应用程序虚拟地址空间中是线性的。等等

正如 nurd_droid 指出的那样,某些处理器根据处理器的模式具有不同的堆栈指针。您可能有一个用于用户/应用程序模式,然后当系统调用发生时系统/超级用户堆栈指针,并且中断发生中断堆栈指针。有些体系结构只有一个堆栈指针......有些体系结构堆栈不在主内存空间中堆栈和堆栈指针隐藏在逻辑中,您并没有真正看到它(通常在这种情况下堆栈大小非常有限并且可以如果您不管理堆栈使用情况,则会自行滚动或其他坏事)。

于 2013-05-29T19:05:56.463 回答
1

堆栈是一种后进先出 (LIFO) 类型的数据结构,过程语言使用它在进行函数调用或发生中断或准备上下文切换之前执行推入/弹出局部变量、CPU 寄存器、返回地址。

变量、寄存器的弹出顺序与它们被压入堆栈的顺序完全相反。

堆栈可以在内存中向上或向下增长。这将取决于微控制器。

此外,许多微控制器具有多个堆栈。1) 用户堆栈 2) 异常堆栈或中断堆栈

如果使用 RTOS,那么每个进程/线程/任务将有自己的堆栈。在这种情况下,用户 SP 微控制器寄存器将由上下文切换例程重新分配,以指向当前活动进程/线程/任务的堆栈。

异常堆栈或中断堆栈在系统中共享。

于 2013-05-29T16:25:02.330 回答