Mon*_*nke 5 c compiler-construction compilation bcpl
我正在研究编译器引导,并且研究了 Golang 如何从源代码实现引导,即通过构建用 C 实现的 Golang 的最新版本并使用生成的可执行文件来编译较新的 Go 版本。这让我很好奇如何用 C 来完成同样的事情。你能在一台几乎什么都没有的计算机上构造一个 C 编译器吗?如果不是,那么我如何相信我使用的编译器的二进制文件不会自动填充它用间谍软件编译的二进制文件?
相关问题,既然第一个C编译器是用B编写的,而B是用BCPL编写的,那么BCPL是用什么编写的?
\n\n你能在一台几乎什么都没有的计算机上构建一个 C 编译器吗?
\n
主要问题是(在 2021 年)你将如何为该计算机编写程序!你会如何输入它?
\n在 20 世纪 70 年代,计算机(如IBM 360大型机)有许多机械开关来输入某些初始程序。在 20 世纪 60 年代,他们拥有更多,例如IBM1620。
\n今天,您将如何输入初始程序?您考虑过使用Arduino吗?甚至示波器也包含带有程序的微处理器......
\n几年前,今天的一些爱好者已经设计(并花费了大量资金)制造带有机械继电器的计算机的计算机。这些可能比您可以购买的最便宜的笔记本电脑(或电脑鼠标内的微控制器 - 并且您的鼠标也包含一些软件)慢数千倍。
\n您还可以购买许多分立晶体管(例如数千个2N2222)并通过焊接它们来制造计算机。
\n即使是便宜的主板(例如MSI A320M A-PRO)现在也有一些称为UEFI或BIOS的固件程序。它是随该程序一起提供的……据传大部分是用 C 语言编写的(几十万条语句)。
\n在某些方面,计算机芯片是用VHDL、SystemC等编码的“软件”……等等……
\n这是一个假设的故事......
\n想象一下,您今天有一台笔记本电脑,在某个孤岛上运行小型 Linux 发行版(\xc3\xa0 la Robinson Crusoe),没有任何互联网连接 - 但有书籍(包括Modern C和一些有关 x86-64 汇编和指令集架构的书籍以及许多其他纸质书籍)、铅笔、纸张、食物和大量的时间。想象一下,系统没有任何 C 编译器(例如,因为您刚刚gcc从某些Debian发行版中错误地删除了软件包),而只有GNU binutils(即链接器ld和汇编器gas)、一些二进制形式的编辑器(例如GNU emacs或vim )、GNU bash和GNU make作为二进制包。我们假设您有足够的动力花几个月的时间来编写 C 编译器。我们还假设您可以访问某种纸质形式的手册页(特别是elf(5)和ld(1) ...)。我们必须假设您可以使用od(1)和less(1)检查二进制形式的文件。
然后你可以在纸上用EBNF 表示法设计 C 语言的子集 \xc2\xb5C 。经过几个月的努力,您可以编写一个小型汇编程序,直接执行syscalls(2)(请参阅Linux Assembly HowTo)并解释 \xc2\xb5C 语言(因为编写解释器比编写编译器更容易;例如阅读Dragon书,以及 Queinnec 的Lisp In Small Pieces和 Scott 的编程语言语用学书)。
\n一旦你有了微型 \xc2\xb5C 解释器,你就可以在 \xc2\xb5C 中编写一个简单的 \xc2\xb5C 编译器(因为 Fabrice Bellard 已经能够编写他的tinyC编译器)。
\n调试完 \xc2\xb5C 编译器后,您可以扩展它以接受 C 的所有语法和语义。
\n一旦您拥有了完整的 C 编译器,您就可以改进它以更好地优化,也许可以扩展它以接受 C++ 的一小部分,并且您还可以编写受Frama-C启发的静态 C 代码分析器。
\n附言。Bootstrapping 可以概括很多 - 请参阅 Pitrat 关于引导人工智能的博客(Jacques Pitrat,生于 1934 年,去世于 2019 年 10 月)和RefPerSys项目。
\n