为什么C语言被用于编写驱动程序和操作系统代码?

11

为什么使用C语言编写驱动程序和操作系统代码?

是否存在大小问题?

是否有其他语言编写的驱动程序?

XP、Vista和Solaris是用哪种语言编写的?


1
大小是问题的一部分,但速度也很重要。C语言轻便快速,而且经过了尝试、测试和验证,我想这就是它的优点吧 :p - mpen
2
马克:注释是用于注释的。答案在下面。你提供了一个答案。 - abelenky
2
C程序员做得更好、更完美,就是这么简单。 - Arc
2
C很棒。C打败其他语言。C还能点燃火焰。C太酷了。 - SuPra
12个回答

25

C语言编译成机器代码,不需要任何运行时支持语言本身。这意味着可以编写可以在文件系统、虚拟内存、进程以及其他除寄存器和RAM之外的任何东西存在之前运行的代码。


5
尽管这个说法在某种程度上可能是正确的,但你必须小心你使用的语言特性,因为如果我没记错的话,浮点数操作,至少转换,仍需要 C 运行时库。虽然如此,与许多其他语言不同,C 运行时库的代码可以被嵌入到应用程序中。很多人忽视的问题是,加载程序本质上必须用汇编语言编写,除非你有一个 C 编译器可以编译适合计算机的引导映像。 - user109878
2
@Webboy42,如果你的C代码已经在内存中(例如在微控制器或BIOS中),那么你只需要在复位向量上放置几个指令即可跳转到C代码的开头。这样一小段机器码可以逐位手动构建,无需汇编器 :) - Theran
1
现代架构也不需要运行时库来进行浮点数转换,这可以通过调用例如fistp操作码来实现。 - Crashworks
11
“C可以被编译成机器码,且不需要任何语言本身的运行时支持。” 这是编译器的一个特性,而不是语言本身的特性。 - jason
1
此时此刻,我不确定这是否重要。使用交叉编译器,您可以重新编译系统以在任何架构上运行。一旦您考虑到这一点,编译运行时可能比移植和重新编译1000个应用程序更好/更可靠。我认为这更多是惯性的问题,大多数我所知道的以操作系统为中心的工程师并不真正愿意改变如此重要的事情。 - Bill K
显示剩余3条评论

23
在安全关键环境中(如航空电子学、航天器、医疗设备、交通运输、过程控制的控制软件),系统(以及驱动程序)通常使用Ada甚至SPARK/Ada编写。
需要澄清的是:C通常被理解为相当低级的语言,几乎就像汇编本身的“宏语言”,这也是它的强项(速度、大小、可移植性)所在。
另一方面,Ada是专门为安全关键应用而设计的,考虑到可验证性,引用Ada 2005 for Mission-Critical Systems

由于其精心设计和建立高完整性系统的明确指南的存在,Ada [9] 是许多关键系统的首选语言 [10]

这也是Ada支持强类型的支持以及其他一些重要功能的原因(引用design for safety)。
编程语言在安全相关系统中的适用性差异很大。Carré等人确定了影响语言适用于高完整性应用程序的六个因素[Carré1990] 。这些是:
- 逻辑完备性 - 定义复杂度 - 表现能力 - 安全性 - 可验证性 - 有界时间和空间约束
没有标准编程语言在所有这些领域表现良好,尽管一些语言(如Pascal和Ada)比C或C ++等语言表现更好。在高度关键的应用中,“可验证性”非常重要。某些语言允许使用强大的软件验证工具对代码执行广泛的静态测试,以检测一系列编程错误。
选择编程语言时一个重要问题是可用编译器和其他工具的质量。对于某些语言,有可验证的编译器可用。虽然不能保证完美,但验证可以极大地增加我们对工具的信心。不幸的是,验证编译器仅适用于少数语言,例如Ada和Pascal。除了编译器之外,关键系统的开发人员还将使用各种其他工具,例如静态代码分析软件包。可以对一段代码执行的静态测试因所使用的语言而异。为了帮助这个过程,通常会将某些语言中使用的功能限制在“安全子集”中。良好结构和定义的语言,例如Ada、Pascal和Modula-2的子集,允许执行许多测试,例如数据流分析、数据使用分析、信息流分析和范围检查。不幸的是,这些测试中的许多测试无法在C和C++等语言上执行。

这个问题的讨论范围已经足够广泛了,进一步深入的细节就不再讨论。但你可能需要查看以下一些指针:

如果有人想进一步了解Ada,请查看:Ada编程(维基教科书)

甚至有一些专门为高度关键应用程序开发的编程语言,例如JOVIALHAL/S,后者被航天飞机计划使用。

是否有用其他语言编写的驱动程序?

我见过一些特殊硬件的Linux驱动程序是用Ada编写的,但不知道其他操作系统怎么样。但是,这些驱动程序通常最终会包装C API。


1
能否解释一下为什么选择Ada而不是C呢?听起来非常有趣。 - Milan Babuškov
3
我已经重新修改了答案,增加了更多的细节和进一步的观点。希望这能有所帮助。 - none

14
因为C具有速度、低内存使用、对硬件的低级访问和流行度等最佳组合。
大多数操作系统都有用C编写的内核,而在其上编写的应用程序则使用C、C++、C#或Obj-C。

据我所知,至少在操作系统内核的最低层需要一些汇编语言。然而作为一个非操作系统开发者,我对此可能会有所错误。 - user109878
2
只是引导程序,我认为。 - John T

14

C语言是除汇编语言外最易于在裸机硬件上“入门”的语言。使用C语言(假设您有一个32位的引导加载程序,例如GRUB来执行艰难的模式切换),您只需创建一个小的crt0.asm文件来设置堆栈,然后就可以使用该语言了(不包括libc)。而使用C++,您必须担心动态转换、异常、全局构造函数、覆盖new等等。使用C#,您必须移植.NET运行时(单独需要一个内核),而我不确定Obj-C的要求如何,但我肯定它也有一些要求...

对于驱动程序而言,C语言就是最简单易用的语言。它不仅易于入门,而且易于了解机器级别的操作过程。没有运算符重载会让您困惑之类的事情。当然,在“好”的环境下这很方便,但在Ring 0中,一个坏指针不仅会导致应用程序崩溃,通常还会导致三倍错误(重新启动)、蓝屏或内核恐慌。你真的喜欢了解你的机器中发生了什么。


13

"为什么我们使用C语言编写驱动程序和操作系统代码?"

这样程序员就不必为每种新机器的每种新汇编语言学习新的语法。

"是否有用其他语言编写的驱动程序?"

从历史上来说,是用汇编语言编写的。我不记得PL/S或BLISS是否可以用于驱动程序。也许是B语言。现代一些勇敢的人使用C++,但他们必须非常小心。在某些情况下,C++可以更容易地用于用户模式驱动程序。


11

Lisp机器的操作系统使用Lisp语言编写,这表明您不必使用C或汇编语言。由于廉价个人电脑的出现,Lisp机器业务被摧毁了,而这些个人电脑的操作系统当然是用C和汇编语言编写的。


8

C语言是最早适合编写操作系统的语言之一(不包括汇编语言),因此它很早就被广泛使用。虽然其他语言也适用于编写操作系统,但由于其悠久的历史和程序员对其结构和语法的熟悉,C语言仍然很受欢迎。


+1 - 这让我想起了“Unix和C是终极电脑病毒”的说法。 - jwd

4

C语言也是一种教授内存管理知识的语言,同时它也足够底层,能够展示硬件和软件之间的障碍。这在当今许多方法论中是罕见的,因为它们更倾向于抽象化,高于任何硬件级别。我发现C语言是学习这些知识的好方法,同时还能编写快速的代码。


3
请记住,C语言最初是为编写操作系统(在这种情况下是Unix)和类似的底层内容而开发的。它非常接近系统架构,并且不包含我们想要控制其确切工作方式的任何额外功能。但请注意,操作系统的其余部分,包括编程库,不必像内核一样用相同的语言编写。内核函数通过中断系统提供,并且实际上此类编程库可以用支持汇编程序段的任何语言编写。
如今最流行的操作系统都是用C语言编写的:Windows,Linux和许多其他Unix克隆版,但这并不是规则。有一些面向对象的操作系统,其中内核和编程接口都使用面向对象语言编写,例如:
- NeXTSTEP - Objective-C - BeOS - C++ - Syllable - C++
请参阅:维基百科上的面向对象操作系统 请注意,在Linux中,可以使用其他语言编写内核驱动程序(但不建议这样做)。无论如何,当它运行时,所有内容都将变成机器代码。

NeXTSTEP操作系统的内核(称为Mach)不是用C或Objective-C编写的。 - Rudolf Adamkovič

2

"C语言编译成机器码,不需要对语言本身进行任何运行时支持."

"这是C语言最好的特点。"


1
这适用于许多编程语言:Pascal、Qbasic、汇编。C++。 - Frames Catherine White
同意,所有编程语言都可以做到C语言所能做到的。 - Mandrake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接