1

我们正在开发一个玩具操作系统作为课堂作业。我在编写内核恐慌函数时遇到了一些麻烦。

它应该保存所有寄存器,调用一些类似 printf 的函数,然后打印保存的寄存器并停止 cpu。现在它被定义为一个宏:

#define panic(...) \
    do{ \
        asm volatile("SAVE_REGISTERS %1\n\t" : "m="(_panic_context)); \
        _panic_printk(&_panic_context, __VA_ARGS__); \
    while(0)

_panic_context是一个全局变量,包含线程的已保存寄存器和更多内容。问题出在SAVE_REGISTERS. 它是在汇编头文件中某处定义的宏,但我不知道如何包含它。文件中的简单#include 显然不起作用。我试过用谷歌搜索和写有趣和绝望的东西(比如汇编字符串中的#include :-))但没有任何帮助。你有什么想法如何解决这个问题吗?

我们正在使用 GCC 并为 MIPS 编译(在模拟器中运行 :-))

编辑: SAVE_REGISTERS.macro SAVE_REGISTERS... 定义。它不能在 C 宏中,因为它在其他汇编模块中使用。我不能用它制作 .S 文件,因为恐慌必须是可变的。或者至少我想不出任何其他方法来做到这一点。

4

2 回答 2

3

我认为您误解了宏的工作方式。它们在任何其他编译发生之前被扩展。您不能asm用来发出一些包含宏的代码,因为该宏永远不会被扩展。

相反,您可以尝试定义SAVE_REGISTERS为使用该asm语句构建汇编代码的 C 宏:

#define SAVE_REGISTERS(x) \
   asm volatile ("movx ax, %1", ...);

那么你可以做

#define panic(...) \
do { \
    SAVE_REGISTERS(_panic_context); \
    _panic_printk(&_panic_context, __VA_ARGS__); \
} while(0);
于 2009-10-21T16:23:05.830 回答
2

我没有 MIPS 系统,但是在我的 x86 loonix 盒子上我尝试#include并发现这#是注释字符,所以我尝试.include并在我引用文件名时立即工作: .include "something.i".

现在,如果您有汇编代码的头文件和有组织的基础结构,我不得不想知道为什么您首先要使用内联 asm 来执行此操作。为什么不直接制作一个真实的.s.S文件,包含汇编头文件,并使其成为您系统中的一流模块?

我已经看到用asmlocore.S完成的小型杰作,即使是在他们的Makefile, go figure中已经有的项目中也是如此。

于 2009-10-21T16:15:08.130 回答