📄 00000005.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>From: <A HREF="mailto:u8123033@cc.nctu.edu.tw">u8123033@cc.nctu.edu.tw</A> (Paladin Mu) <BR>Newsgroups: cis.comp,cis.announce <BR>Subject: [资讯人园地] Compiling a Compiler ! <BR>Organization: Dept. of Computer & Information Science, NCTU, Taiwan <BR> <BR>[资讯人园地] <BR> <BR> C o m p i l i n g a C o m p i l e r <BR> <BR> <BR> CIS 85 <BR> 穆信成 <BR> <BR> <BR> <BR> UNIX是以C语言写成的。使用C语言的其中一个优点是造成了UNIX的可携性。 <BR>另一方面,工作站的销售对象是需要大量计算的工程师、科学家等等;因此不同 <BR>於PC,在工作站级以上的电脑上,compiler是一项附在作业系统中的基本配备。 <BR>UNIX系统中必定附有C compiler。既然要保持可携性, UNIX系统里面所附的的C <BR>compiler也得和UNIX系统一样,用C写作。 <BR> <BR> C compiler本身,也是用C写的。当一个语言的compiler 也用该语言本身来 <BR>写的时候, 便会发生一些有趣的事情。 也许您会问, 既然电脑上面已经有 <BR>C compiler了,那麽我们要再去compile另一个compiler的source code作什麽? <BR>答案可能是,原有的内建C compiler可能比较简陋或著老旧,因此我们想把新的 <BR>compiler用旧的compiler编译,然後当成系统内建的compiler用。换句话说,我 <BR>们就这麽扩充了系统的内建compiler。 <BR> <BR> Glasgow大学的GRASP计划,也用这样的过程发展他们的Haskell compiler。 <BR>Haskell是一个functional language(85级同学记得Programming Language课中 <BR>提到的functional programming吗?)。Functional programming总是带有较多 <BR>的学术味而缺乏实用经验。Haskell语言本身仍有不少需要再扩充的空间。GRASP <BR>计划用 Haskell 来写Haskell compiler:先从简单的写起, 产生一个最原始的 <BR>Haskell compiler,然後用这套原始的Haskell语言写一个功能较强的 compiler <BR>(把原来的Haskell扩充了),再用第二版的 Haskell 语言写第三版的compiler <BR>....。由於都是compiler,因此并不会减低效率。一个好处是,每次扩充语言, <BR>接下来立刻用新的语言写compiler,於是我们可以立刻看出新加功能是否有用处? <BR>该怎麽用?如此累积的经验,正可以作Haskell语言以後发展设计的参考。GRASP <BR>计划的理想就是″把functional proramming带出实验室″。 <BR> <BR> UNIX的创造人之一,Ken Thompson,在他的 Turing Award Lecture中,便 <BR>由这个主题加以发挥,说了一些有趣的故事。C 是一个被拿来写作业系统的语言。 <BR>写作业系统的人很难忍得住诱惑,不在系统里面装些後门的。想想看,如果我写 <BR>作业系统时,偷偷在login 的部份加一段程式码,使得全世界的这套作业系统只 <BR>要看到我的account和密码就让我进去,给我root权限,这该是多爽呀。 但是我 <BR>不能直接在 login 的 source code 里面这样写,否则一下就被人抓到了(既然 <BR>source code流通,就是要给人看的呀)。 该怎麽办呢?就从compiler里面动手 <BR>脚,称作patch1吧:在compiler中多加一道手续, 如果发现被compile的原始程 <BR>式″疑似″在作login动作,就把它开个漏洞,让我进得去。 <BR> <BR> 但是这样也不见得行得通。Compiler以後也会改版,新版的compiler可能不 <BR>是我在写。装系统的人也不见得用我的compiler。怎麽办呢?於是我在compiler <BR>的source code中作第二次手脚,称作patch2:如果这个compiler觉得在compile <BR>的程式″疑似″另一个 compiler 的 source 的话,就加入上面的patch1和这个 <BR>patch2本身。 <BR> <BR> 好,现在作业系统推出了,CC1 是我写的内建compiler,其中有我动的两个 <BR>手脚。现在某人在compile UNIX, 不得不用这个compiler。然而CC1 中已经有了 <BR>patch1,於是一旦compile到login, compile出来的login程式就被动了手脚。只 <BR>要看到我的名字,就一定让我进系统,给我root权限。 <BR> <BR> ,--------. +-------------+ ,-----------. <BR> | login | | Compiled | | login | <BR> | source |=====>| by CC2 |=====>| Program | <BR> | (clean)| | patch 1作用 | |(受感染了!)| <BR> `--------' +-------------+ `-----------' <BR> <BR> 既然 compiler CC1会作怪, 那麽自己写 compiler 总可以了吧? 然而,C <BR>compiler还是得用C写,写好了之後,用谁来compile呢? 只有用CC1来compile。 <BR>CC1发现新写的CC2是一个compiler的source code,於是 patch2 就发挥作用了。 <BR>CC1会在CC2中也加入patch1和patch2。於是CC2也被″污染″了。 <BR> <BR> ,--------. +-------------+ ,-----------. <BR> | CC2 | | Compiled | | CC2 | <BR> | source |=====>| by CC1 |=====>| Program | <BR> | (clean)| | patch 2作用 | |含 patch1,2| <BR> `--------' +-------------+ `-----------' <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -