2014-08-23 66 views
19

是否可以在C中完全编写操作系统?是否可以在C中完全编写一个操作系统?

通过完全,我包括一切都交给了引导程序,而不是BIOS/UEFI。

+1

这取决于你说“操作系统”时的实际含义。我读过一本关于ARM的书,可能有一些Cortex-M处理器(非常有限,用于MCU),但很可能在许多其他核心上,您将被迫至少使用一些基本的程序集组态。 – user35443 2014-08-23 09:10:35

回答

20

问题的传统答案是“你能写一个完全在C中的程序”是“否”。原因是C程序没有办法建立自己的堆栈。

几乎每一个处理器有需要指向至少一个寄存器,它指向在堆栈(通常称为帧指针)的当前地址和有时有一个第二寄存器(通常称为堆栈指针)堆栈中下一个未使用的地址。没有办法在语言本身中使用任何表达式或语句来将堆栈指针或帧指针设置为绝对值。 (过程调用和返回可以添加和从堆栈指针减,但有没有办法把它初始化为已知值。)

POSIX定义了一组函数,setcontextgetcontextmakecontextswapcontext(几乎总是写在至少部分是汇编器),这将使您能够读写堆栈和帧指针。

不幸的是,setcontext家庭的功能没有得到广泛实施。

7

理论上是的,但不是一切。

引导加载程序和实模式的东西,你可以找到一些旧的16位编译器(例如,涡轮增压C),告诉他要输出纯二进制,并把它写所有的东西。
,或者在GCC你可以把asm(".code16gcc")在你的代码的顶部,但我不建议这一点,因为GCC是不能够直接输出16位代码,结果汇编程序可能需要超过512个字节。

对于其他的东西,抵消大会的使用是不可能的。
是的,您可以隐藏内联函数(IN \ OUT,CRx寄存器和内容)中的所有组装线,但对于其他内容(如中断),您将被迫使用组装。

编辑
现在GCC(4.9.0)支持-m16选项使16位代码生成,因此该组件使用可以对之类的东西启动扇区/引导加载器可以进一步减小(一些比特仍然需要它虽然)。

7

这取决于你用C

意思

如果你的意思是由ISO定义的,只在定义行为依托,而你认为​​在硬件上运行一个常见的各种操作系统的标准C语言编程,那么不,在C中编写实用的操作系统是不可能的,因为C缺乏很多设施,特别是访问硬件和操纵单独的程序。

是可能的写操作的系统,由C程序并且仅至C设施提供输入/输出,但不是实际的硬件上运行的OS。您可以通过这种方式为机器及其操作系统编写仿真器。

如果你允许实现特定的行为,那么答案是平凡的,因为实现允许添加他们认为合适的扩展。这绝对有可能有一个C实现,其中operating_system();是实现操作系统的程序的源代码。

如果您的意思是是否可以使用典型的C编译器在不使用任何程序集的情况下构建操作系统(包括运行时环境),那么答案通常是否定的,因为C编译器通常缺少一些仅为对操作系统编写者的兴趣,比如执行上下文切换和建立堆栈所需要的东西。然而,这不是绝对的规则。如果您喜欢,它取决于运行时环境的哪些部分来自编译器编写器,哪些部分来自OS编写器。

+0

在相当数量的平台上编写操作系统,而不用编写单行汇编语言(仅使用编译器附带的库)是可能的,尽管通常最好是编写至少一点机器码。例如,在许多平台上,人们可以定义一个'jmp_buff'和'char []'的联合体(作为静态的),让程序入口点分别写入其中的字符,然后不加入“longjmp”使任何堆栈的使用[请注意,memcpy甚至结构分配可能是一个子程序调用,因此不好]。 – supercat 2015-06-30 15:53:30

+0

使用一点点内联汇编来设置堆栈可能会比逐个创建'jmp_buff'更清洁(并且可能更具可移植性),但是使用诸如'jmp_buff'之类的技术将使它成为可能,许多实现,建立系统而不需要编译C代码以外的任何东西。 – supercat 2015-06-30 15:55:53

相关问题