

作者|刘欣
这是我星球上的一个问题: “ C语言是用哪种语言编写的?”
实际上,它是: 在运行C语言之前,必须对其进行编译. C语言编译器从哪里来?用什么语言?如果使用C语言本身编写,那么首先是鸡蛋还是鸡肉?
我们假设世界上没有编译器. 让我们从机器语言开始,看看该怎么做.
机器语言可以直接由CPU执行,不需要编译器.

然后是汇编语言. 尽管汇编语言只是机器语言的助记符,但需要将其编译为机器语言才能执行. 无法用机器语言编写第一个编译器(以后将不再使用)).
解决了汇编语言的问题,我们迈出了一大步. 这时,我们可以使用汇编语言编写C语言编译器. 我们说这是C编译器的祖先.
使用此祖先,您可以编译任何C语言程序. 是否可以用C语言本身编写编译器?只需与您的祖先一起编译.
好的,经过了很多层之后,我终于有了用C编写的编译器,这确实很麻烦.
这时,可以放弃使用先前程序集编写的C语言编译器.
当然,如果其他高级语言已经出现在C语言之前,例如Pascalc语言对应汇编语句,则可以使用Pascal编写C语言编译器.

据说第一个Pascal编译器是用Fortran编写的. 作为第一种高级语言Fortran,其编译器应使用汇编语言编写.
关于编译器,这里有一个有趣的图例:
传奇的Unix发明者之一肯·汤普森(Ken Thompson)走进贝尔实验室的任何Unix机器,输入他的用户名和密码,并以root用户身份登录!
贝尔实验室(Bell Labs)有大量人才,还有其他一些大母牛发誓要找出漏洞. 他们通读了Unix C源代码c语言对应汇编语句,最后找到了用于登录的后门. 清理后门后,他们编译了Unix并运行了它,但是Thompson仍然能够登录.
有人认为编译器可能有问题. 编译Unix时,植入了后门,因此他们用C语言重新编写了一个编译器,并使用新的编译器再次编译了Unix. 这终于是世界. 太和平了.
但是它仍然不起作用,汤普森仍然可以使用root登录,这确实很崩溃!

汤普森后来亲自解开了秘密. 这是第一个有问题的C语言编译器. 当然,此编译器在编译Unix源代码时会植入后门. 这还不够. 更重要的是,如果您使用的是我用C语言编写的新编译器,那么我绝对需要将其编译为二进制代码. 我应该用什么来编译它?仅使用汤普森编写的第一个编译器进行编译. 好吧,您编写的编译器将受到污染. 现在,您的编译器将编译Unix,并且还将植入后门: -)
谈到这一点,我记得几年前的XcodeGhost事件. 简而言之,木马被植入了Xcode(非官方下载),因此XCode编译的iOS应用程序都被污染了. 这些应用可以被黑客用来做非法的事情.
尽管此XCodeGhost远远落后于Thompson的XCodeGhost,但它提醒我们,在下载软件时,您必须经过正式渠道,从官方网站下载,检查网站的HTTPS标准,甚至验证校验和.
有些人可能会问: 与慧慧一起撰写《 Hello World》的部分非常麻烦. 有人可以用它来编写复杂的编译器吗?有可能吗?
当然,当开发第一代Unix时,甚至没有C语言. Ken Thompson和Dennis Ritchie逐行组装淘汰了Unix. WPS的第一版是由邱伯钧使用Hui编写的. Turbo Pascal编译器也是由Anders使用Hui编写的. 普通人无法想象神的能力.
对于编译器,您还可以使用“ snowball”方法进行开发:

仍然使用
C语言作为示例. 在第一个版本中,可以首先选择C语言的子集. 例如,仅支持基本数据类型,流控制语句和函数调用...我们将此子集称为C0.
然后用汇编语言编写一个编译器,并且只获得该语言的子集C0,这使得编写起来容易得多.
语言C0可以工作,然后我们扩展此子集,例如,添加结构,指针.... 调用新的语言C1.
谁为C1编写了编译器?当然是C0.
等到C1正常工作,再扩展语言功能,用C1编写编译器,然后获得C2.
然后C3, ...终于获得了完整的C语言.
此过程称为引导,在中文中称为引导.
作者简介: 刘欣,畅销书《 Coder Turning Over》的作者,有15年以上的开发经验,曾任IBM架构师,曾领导过许多企业应用程序体系结构设计和开发工作;对技术本质的洞察力,善于用故事来解释复杂技术.
【END】
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-280774-1.html
海浪不会不在