强制函数在进行函数调用之前恢复所有寄存器

时间:2015-08-09 11:39:23

标签: c assembly operating-system embedded

我使用的是EK-LM4F120XL主板,它包含一个cortex-M4处理器。我还使用GCC-ARM-none-eabi作为工具链。

我正在建立一个小业余爱好项目,慢慢成为一个操作系统。其中一个重要的部分是我需要切换寄存器来切换进程。这发生在一个中断内,这个特定的处理器确保所有临时寄存器(r0-r3,r12,lr)被推送到进程堆栈。所以为了继续我需要将r4-r11和SP的内容写入内存中的一个位置,我需要加载新进程的r4-r11,加载其堆栈指针并返回。此外,lr值包含有关被中断的进程的一些信息,因此我也需要来自该寄存器的信息。

所有这些都有效,因为我是在汇编中写的。我将汇编函数直接链接到中断,因此我可以完全控制寄存器的内容。 C和内联汇编的组合不起作用,因为编译器通常会将一些寄存器推送到堆栈,这是致命的。但是操作系统正在增长,并且上下文的变化正在增长:现在还有一些全局变量需要改变等等。所有这些都可以在汇编中实现,但它变得很痛苦:汇编很难阅读和调试。所以我想要一个C / Assemlby组合。基本上我正在寻找这样的东西:

void contextSwitch(void){
    //Figure out what the next process will be
    //Change every variable that needs changing

    // Restore register state to the moment of interrupt. The following function will not return in the sense that it will end the interrupt.
    swapRegisters(oldProc, newProc);
}

然后在汇编中只写swapRegisters。有没有办法实现这个目标?我的解决方案是最好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

在C中没有直接访问CPU寄存器的可移植方法;您将需要汇编程序,内联汇编程序,编译器内在函数或内核库(使用汇编程序代码)。

有关Cortex-M如何完成的详细信息在其他地方已有详细介绍,可能过于复杂而无法重复:在Cortex-M4(F)中执行此操作的具体细节在ARM信息中心网站{{3 }}。除了FPU考虑因素外,Cortex-M3的方法大致类似,提供了上下文切换的M3特定描述here

由于你不能有足够的解释,因为不同的作者使某些事情比其他人更清楚,或者提供更好或更直接适用的例子,in this Embedded.com article - 也是基于M3的,但如果不使用FPU,则可以在M4上使用M4没有FPU。并here's another