函数调用和上下文保存到堆栈

时间:2017-01-25 14:47:51

标签: function stack rtos

我对微控制器的实时操作系统非常感兴趣,所以我正在对这个主题进行深入的研究。在高层次,我理解操作系统的所有一般机制。

为了更好地学习它,我决定编写一个非常简单的内核,除了上下文切换之外什么都不做。这给我带来了许多额外的实际问题。我能够应付其中的许多但我仍然怀疑主要的事情 - 保存当前任务的上下文(所有CPU寄存器和堆栈指针)并恢复新任务的上下文。

通常,操作系统会使用一些功能(比如说, OSContextSwitch())来保留上下文切换的所有操作。 OSContextSwitch()的主体主要用汇编语言编写(C体函数中的内联汇编)。但是当调度程序调用 OSContextSwitch()时,据我所知,在函数调用中,编译器会在堆栈中保留一些CPU寄存器(实际上由编译器生成的代码)编译器)。

最后,问题是:如何知道哪些CPU寄存器已经由编译器保存到堆栈中,以便我可以保留其余的?如果我保留所有寄存器而不管编译器的行为,显然会有一些堆栈泄漏。

1 个答案:

答案 0 :(得分:1)

这样的函数应该写成纯粹的汇编(因此 NOT C函数中的汇编块)或者#34;裸露的" C功能只不过是装配块。在两者之间做任何事都是弄乱事情的直接道路。

至于你应该保存的寄存器 - 通常你需要知道你的平台的ABI,它说一些寄存器由调用者保存,一些寄存器应该由被调用者保存 - 你通常需要保存/恢复一些通常由被叫方保存。如果你保存所有这些都不会发生任何错误 - 你的代码只会稍微慢一些并使用更多的RAM,但这将是一个很好的起点。

这是ARM Cortex-M微控制器的典型上下文切换实现 - https://github.com/DISTORTEC/distortos/blob/master/source/architecture/ARM/ARMv6-M-ARMv7-M/ARMv6-M-ARMv7-M-PendSV_Handler.cpp#L76