【问题标题】:Includes in inline assembly包括在内联汇编中
【发布时间】:2010-12-08 18:38:47
【问题描述】:

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

它应该保存所有寄存器,调用一些类似 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 文件,因为恐慌必须是可变的。或者至少我想不出任何其他方法来做到这一点。

【问题讨论】:

  • SAVE_REGISTERS 究竟是如何定义的?

标签: c gcc assembly operating-system inline-assembly


【解决方案1】:

我认为您误解了宏的工作原理。它们在任何其他编译发生之前被扩展。您不能使用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);

【讨论】:

  • 虚拟循环是为了确保宏后面有一个分号,我想。
  • 虚拟 do 循环是多语句宏中的一种常用技术,例如,当在 if 语句中使用时,它们会表现良好。它应该留在宏中(但应该添加右大括号)。见stackoverflow.com/questions/154136/…
  • 啊,好吧,我不知道那个约​​定。编辑了答案。谢谢。
【解决方案2】:

我没有 MIPS 系统,但是在我的 x86 loonix 机器上我尝试了 #include 并发现 # 是评论字符,所以我尝试了 .include 并且在我引用后立即起作用文件名:.include "something.i".

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

我已经看到用 asm 完成的小型杰作,即使在他们的 Makefile 中已经有 locore.S 的项目中,去看看...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-20
    • 2021-02-22
    • 2013-07-23
    • 1970-01-01
    • 2013-11-26
    • 2014-07-19
    • 1970-01-01
    • 2019-03-14
    相关资源
    最近更新 更多