为什么某些操作系统事件处理是用asm而不是c编写的?


17

我的问题是,为什么现在内核本身主要使用C编写某些操作系统事件处理时,仍然使用汇编语言而不是诸如C之类的高级语言编写?


5
“大部分在c中”-猜猜剩下的是什么?;)
goldilocks 2015年

@goldilocks很好,它正在组装中。但是,为什么其他部分在c中呢?
MAKZ 2015年

4
我不是专家,但是有一些底层硬件相关的事情无法用C来完成。这些通常是特定于体系结构的。为此,通常在C代码中使用“内联ASM”,例如,foobar()将使用内联汇编在一个平台上以一种方式在另一种平台上以另一种方式进行定义。这样可以使对asm的使用减至最少,但不能完全避免。
goldilocks 2015年

您如何在C中设置全局描述符表指针寄存器?
user253751

Answers:


24

该语言提取了对CPU寄存器的访问权限,处理事件时的操作系统必须保存上下文,因此它需要在事件发生时访问寄存器,从而破坏了C规范。


这实际上是主要原因。某些嵌入式C编译器确实具有允许其寻址寄存器的扩展名(通常通过预先声明的全局常量/变量)。之所以能够做到这一点,是因为它们只针对一种架构。但是通用C编译器的目标是太多不同的体系结构,以致于无法合理地进行此类扩展。因此,他们通常只实现一种asm嵌入机制(此外,这会使它们成为非标准的)
slebetman 2015年

18

C是在机器上运行的机器代码的抽象(尽管比大多数其他语言更接近)。

对于那些无法在C中表达的机器代码语句,以及可能出于C编译器程序集未提供的额外优化的考虑,它们大多以内联汇编程序的形式进行

在内核源代码树,这是存储在arch/<arch>include/asm-<arch>其中<arch>一个特定的架构名称。实际上,它只是完整内核源代码的一小部分。


6

您不能在C中执行此操作:)

lgdt[xxxx]
mov eax, cr0
or al, 0x01
mov cr0, eax

我正在尝试进入x86保护模式。显然,我仍然可以通过“发出”原始机器代码在C语言中执行此操作,但是仍然可以在需要访问精确消息的情况下使用-多数情况下我不走运。

第二个示例是BootLoader。在x86系统上,要求传统引导代码的长度恰好为512字节,而后两个字节分别为0xAA和0x55(或恰好为55 AA)...使用C编译器确保这样做是一场噩梦,而汇编程序会以一种奇妙的方式工作。

在更多这样的情况下,组装不仅是可取的,而且是唯一的手段。


-5

asm更苗条,并且通常比C与库等联合使用要快得多,并且OS始终在处理大量事件。您希望此功能纤薄而快速。


2
优化C编译器技术已经相当不错。通常,asm会比C快很多,这是一个神话。在任何情况下,这都不是低级操作系统操作使用asm的原因。它主要与无法在C中表示的操作(例如内存屏障)以及为非C调用约定注册舞曲等有关
Celada 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.