为什么某些内核操作无法用C编写

时间:2017-07-18 08:34:49

标签: c assembly kernel

我道歉,如果这应该听起来微不足道,但是我无法找到一种直观的方式去谷歌,为什么一些内核动作如保存寄存器的当前状态和堆栈(仅举几例)写的在大会?为什么它们不能用C语言编写,因为毕竟,大概在编译完成后,我们得到的只是目标代码?此外,当您使用ollydbg时,您会注意到在函数调用之前(在C中),寄存器的当前状态被推送到堆栈

5 个答案:

答案 0 :(得分:4)

编写操作系统时,主要目标是保持最高的抽象,以使代码可以在不同的体系结构上重用,但最终不可避免地存在架构。 / p>

每台机器都以一种通用编程语言无法维持的专业方式执行极低级功能。

任务切换,总线控制,设备中断处理,仅举几例,无法使用高级语言进行有效编码(考虑指令序列,涉及的寄存器以及最终的关键CPU时序和优先级)。

另一方面,使用混合编程(即内联汇编程序)甚至不方便,因为精心设计的模块将不再抽象,包含无法重用的特定体系结构代码。

常见的解决方案是按照最高抽象级别编写所有代码,将专用代码减少到几个模块。这些例程完全用汇编语言编写,通常在提供的输入和预期输出方面很好地定义,因此程序员可以在不同的架构上产生相同的结果。

然后只需切换一组汇编程序就可以编译不同的CPU。

答案 1 :(得分:2)

C不保证它会修改您需要修改的寄存器。

C只是实现了你在代码中编写的逻辑,语言给出的解释将如你所愿,完全隐藏解释背后的细节。

如果你想要一种像GetSchema<T>set the X register with a given value那样的逻辑,因为有时需要在内核中进行,这种逻辑不是由C语言定义的。

答案 2 :(得分:1)

C是一种通用的高级语言,并非特定于一个目标。但是在内核级别,您需要做的事情是C语言根本无法做到的特定目标。启用中断或配置MMU或配置与保护机制有关的内容。在某些目标上,这些项目和其他项目是使用地址空间中的寄存器配置的,但在某些目标上需要特定的汇编语言指令,因此不能使用C,它必须是汇编。如果不是很多,通常至少有一件事你必须为每个目标使用程序集。

有时需要使用正确的指令是一个简单的例子,例如必须使用32位存储来进行某些操作,以确保编译器能够正确使用asm。

答案 3 :(得分:0)

“从异常中返回”没有C等价物。 C编译器无法转换程序集可以执行的所有操作。例如,如果编写操作系统,则需要在中断服务程序中使用特殊的返回函数,该函数可以返回到启动中断的位置,而C编译器无法转换这样的功能,它只能在汇编中表示。

另见Is assembly strictly required to make the "lowest" part of an operating system?

答案 4 :(得分:0)

Context switching非常重要,需要非常快,不应该用高级语言编写。