首页 > 操作系统是C语言写的,那么问题来了

操作系统是C语言写的,那么问题来了

1.比如我们在WINDOWS下想编译自己写的C程序可以用编译软件把写的程序编译下,可是操作系统这个软件最初是怎么编译的?而且编译软件是运行在操作系统下的?
2还有为什么编译器可以直接认识我们写的C代码,或者说JAVA也好GO语言也好,他们只是编译器不同而已么,语言的本质是一样的,只是编译器不同语法不同而已,我这样理解对吗?
3.编译器是为了让本系统下认识这段程序,还是为了让计算机认识呢?就是说程序和编译器和系统有关系吗。

问的有点混乱,大神听懂吗,初学C语言,求指教。


1,操作系统最初是汇编语言(一种人能看懂的二进制)写的,把写好的操作系统编译到不易失的存储介质上。以intel为例,boot之后将检查你指定的设备的前512个字节,如果最后两个字节为0x55,0xAA.将其加载到内存0x7c00处并把pc指向0x7c00,开始运行操作系统。编译软件不一定需要运行在操作系统下。

2,因为你接受了C语言的规约,所以编译器可以直接认识你写的C代码。理解可以说对,因为大部分语言都是图灵完备的。
3,编译器为了让计算机认识程序,特定系统的编译器为了让系统认识程序。程序和编译器和系统没有关系。


去买一本现代操作系统深入理解计算机系统. 先看后面这一本.


编译器是想滚雪球一样滚出来的,一开始用机器语言写一个很功能有限的汇编器(汇编接近机器语言,几乎就是简单的替换,比较好写),然后用它编译更强大的汇编器/编译器。更高级的语言由稍微低级点的语言编写,然后发展到合适的程度之后,某些语言实现了自举,即自己编译自己的编译器。

编译的结果是二进制文件,二进制文件其实是和系统关系并没有那么大,只是一个内存的镜像。具体的Windows或者Linux之间不同的只是封装格式PE/EFI的区别,这些信息只是用来告诉系统该怎么加载这个镜像而已,自己写一个操作系统来加载RAW内存镜像,这样的程序也是可以运行的。如果一个程序没有用系统提供的API,能够直接访问硬件中断的话就和系统无关了。不过现在的系统都有保护,不允许直接调用硬件中断,都是调用系统的API,系统再调用硬件,来执行。

不同语言不仅仅是语法不同,编译结果的执行方式也是不一样的。Java编译结果是字节码,要在Java虚拟机里再解释编译成Java虚拟机的字节码来运行。有些程序类似Go有runtime的概念,能够在运行时自省修改自己。lisp这种语言甚至数据和程序都不区分,数据就是程序。
不过在微观的看,这些都只是运行方式/实现方式不同,但是运行过程都是一样的,这是冯诺依曼体系决定的,即CPU永远执行内存中下一条指令。


1.操作系统最初是用汇编语言写的,然后用汇编写了第一份c语言编译器,然后迭代自举
推荐阅读《软件故事:谁发明了那些经典的编程语言》图灵社区
2.编译器需要对源码进行一层一层的分析
内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。
推荐阅读《编译器设计》第二版 图灵社区
3.让机器认识,一部分功能是无法在操作系统的用户态运行的,需要调用操作系统的函数才能完成,比如IO

推荐阅读《现代操作系统》第四版 和 《深入理解计算机系统》第二版

如果只买一本书看的话就买《深入了解计算机系统》翻译不错


对于编程语言,基本上是这样进化的:

  1. 先用机器语言写出汇编器,然后就可以用汇编语言编程了,然后再用汇编语言编写汇编器。

  2. 先用汇编语言写出 C 编译器,然后就可以用 C 语言编程了,然后再用 C 语言来写 C 编译器。

  3. 有了 C 编译器与 C 语言,就可以在这个基础上再编写高级语言的编译器或解释器或虚拟机了。

  4. 非 C 系语言,进化过程同上。

至于操作系统,先用汇编语言写一个操作系统。Ken Thompson 干过这样的事,他用汇编语言以及他自创的一种解释性语言——B 语言写出来 unix 第一版,是在一台内存只有 8KB 的废弃的计算机上写出来的。然后 Dennis Ritchie 发明了 C 语言,然后 Ken 与 Dennis 又用 C 语言在一台更好的计算机——16 位机器上将 unix 重写了一遍。

至于 Windows 系统,MS 先是买了 QDOS,然后又在 QDOS 里引入了一些 Unix 的元素,然后比尔·盖茨靠着这个买来的系统赚了一大笔钱,然后就在 DOS 系统上开发了 windows 3.1,windows 95 ……


先有鸡还是先有蛋的问题
第一只能下蛋的鸡是从不能下蛋的鸡一点一点进化来的。

计算机也是这样,最早的计算机是插电线插出来的,然后有了打孔纸带,有了机器码,有了汇编,有了各种语言
进化来的

【热门文章】
【热门文章】