关于C语言本身用什么语言写的?|

作者 | 刘欣

这是来自我的星球的一个问题:“C 本身是用什么语言编写的?”

换个角度问,其实是:C语言运行前,必须先编译。C语言编译器从何而来?它是用什么语言写的?如果它是用 C 语言本身编写的,先有蛋还是先有鸡?

让我们假设世界上没有编译器,让我们从机器语言开始,看看该怎么做。

机器语言可以直接由 CPU 执行,无需编译器。

然后是汇编语言。汇编语言虽然只是机器语言的助记词,但也需要编译成机器语言才能执行。没有办法用机器语言编写第一个编译器(将来不会使用它)。

解决了汇编语言的问题后,我们又向前迈出了一大步。这时候我们就可以用汇编语言来编写C语言编译器了。我们说这是 C 编译器的祖先。

有了这个祖先,你可以编译任何 C 语言程序。是否可以用 C 语言本身编写编译器?只需与祖先一起编译它。

OKc语言编辑器是一种,经过这么一层一层,终于得到了一个用C语言写的编译器,真是麻烦。

这时候,前面汇编写的C语言编译器就可以舍弃了。

当然,如果在C语言之前出现了其他高级语言,比如Pascal,那么Pascal可以用来编写C语言编译器。

据说第一个 Pascal 编译器是用 Fortran 编写的。作为第一个高级语言Fortran,它的编译器应该是用汇编语言编写的。

这里有一个关于编译器的有趣传说:

传说 Unix 的发明者之一 Ken Thompson 走到贝尔实验室的任何一台 Unix 机器上,输入他的用户名和密码,然后以 root 身份登录!

贝尔实验室人才辈出,其他一些大牛发誓要找出这个漏洞。他们通读了 Unix 的 C 源代码,终于找到了登录的后门。清理后门后,他们编译了 Unix 并运行了它,但 Thompson 仍然可以登录。

有些人认为编译器可能有问题。在编译Unix的时候,植入了后门,所以他们用C语言重新编写了一个编译器,然后用新的编译器重新编译Unix。.

但是还是不行,Thompson 还能用root 登录,真是郁闷啊!

后来,汤普森自己解开了这个秘密。这是第一个有问题的 C 语言编译器。这个编译器在编译Unix源代码的时候,当然会植入一个后门。新的编译器必须编译成二进制代码。用什么来编译,只有Thompson写的第一个编译器才能编译,嗯,你写的编译器会被污染,你编译Unix的编译器也会植入后门:-)

说到这里,我想起了几年前的 XcodeGhost 事件。简而言之,就是在Xcode中植入木马(非官方渠道下载),从而污染了XCode编译的iOS应用,黑客可以利用这些应用做非法的事情。

虽然这个 XCodeGhost 离 Thompson 还很远,但它提醒我们,在下载软件的时候,一定要走正规渠道,从官网下载,寻找网站的 HTTPS 标准,甚至校验校验码。

有人可能会问:我用汇编写一个Hello World很麻烦c语言编辑器是一种,但是有人可以用它来写一个复杂的编译器吗?可能吗?

当然有可能第一代Unix开发的时候还没有C语言,但是Ken Thompson和Dennis Ritchie在汇编中逐行打出Unix。WPS的第一个版本是邱伯君用汇编写的,Turbo Pascal的编译器也是Anders用汇编写的。大神们的能力,超乎常人的想象。

对于编译器,也可以用“雪球”的方式开发:

以C语言为例,第一版可以先选择C语言的一个子集,比如只支持基本数据类型、流控制语句、函数调用……我们把这个子集称为C0。

然后用汇编语言写一个编译器,只得到这个语言的子集C0,这样写起来就容易多了。

语言 C0 可以工作,然后我们扩展这个子集,例如添加结构、指针……并调用新的语言 C1。

谁为 C1 语言编写了编译器?自然是C0。

等到C1可以工作,再次扩展语言特性,用C1编写编译器,得到C2。

然后是 C3、C4……最后是完整的 C 语言。

这个过程叫做bootstraping,中文叫bootstrapping。

关于作者:刘鑫,畅销书《码农翻身》作者,15年以上开发经验,前IBM架构师,曾主导多个企业应用架构的设计开发;洞察技术本质,善于用故事解释复杂技术。

【结尾】

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论