"Mis keeles C ise kirjutatakse?"
Teisest vaatepunktist on see nii: enne kui C keel töötab, tuleb see kompileerida, nii et kust tuleb C keele kompilaator? Mis keeles see on kirjutatud? Kui see on kirjutatud C-s, kas kõigepealt on muna või kana?
1
Oletame, et maailmas pole ühtegi kompilaatorit, alustame masinkeelest ja vaatame, kuidas.
Masinkeelt saab protsessor otse käivitada ilma kompilaatori vajaduseta.
Siis on assambleekeel, kuigi assemblerkeel on vaid masinkeele mnemoonik, kuid see tuleb ka kompileerida masinkeelde, et käivitada, seega pole muud valikut kui kasutada masinkeelt, et kirjutada see esimene kompileerija (mida tulevikus ei kasutata).
Assambleekeele probleem on lahendatud ja see on suur samm edasi – praegu on võimalik kasutada assemblerkeelt C keele kompilaatori kirjutamiseks, mida me nimetame C kompilaatori eelkäijaks.
Selle eelkäijaga saab kompileerida ükskõik millise C keele programmi, seega kas saab kirjutada kompilaatori otse C keeles? Lihtsalt koosta see koos esivanematega.
Olgu, pärast sellist kihti sain lõpuks C-keeles kirjutatud kompilaatori, mis on tõesti tülikas.
Sel hetkel võib eelmise paketi kirjutatud C kompilaatori maha jätta.
Loomulikult, kui enne C-d oli olemas ka teisi kõrgetasemelisi keeli, näiteks Pascal, siis saaks Pascali abil kirjutada C kompilaatorit.
Esimese Pascal'i koostaja olevat kirjutatud Fortranis. Esimese kõrgetasemelise keelena peaks Fortrani kompilaator olema kirjutatud assemblerkeeles.
2
Siin on huvitav legend kompilaatori kohta:
Legend räägib, et Ken Thompson, üks Unix'i leiutajatest, astus Bell Labsis ükskõik millisele Unix-masinale, sisestas oma kasutajanime ja parooli ning sai sisse logida juurtekaudu!
Bell Labs on täis talente ja mõned teised suured tegijad lubasid selle haavatavuse üles leida, nad lugesid läbi Unix'i C lähtekoodi ja lõpuks leidsid sisselogimise tagaukse, ning pärast tagaukse puhastamist kompileerisid Unixi ja käivitasid selle, kuid Thompson suutis ikkagi sisse logida.
Mõned arvavad, et kompilaatoris võib olla probleem ning Unix'i kompileerimisel paigaldati tagauks, mistõttu kirjutati kompilaator ümber C-s ja Unix kompileeriti uuesti uue kompilaatoriga.
Aga see ikkagi ei tööta, Thompson saab rootiga sisse logida, mis on tõesti laastav!
Hiljem avas Thompson ise saladuse, see oli esimene C-kompilaator, kellel tekkis probleem, see kompilaator paigaldatakse muidugi Unix lähtekoodi kompileerimisel tagauksele, sellest ei piisa, mis veel parem, kui kirjutad uue kompilaatori C-keeles, pead selle kindlasti kompileerima binaarkoodiks, mida kompileerida, kasuta ainult esimest Thompsoni kirjutatud kompilaatorit, okei, sinu kirjutatud kompilaator saab saastunud, sinu kompilaator kompileerib Unixi uuesti, Paigaldan ka tagaukse :-)
Muide, mulle meenub mõni aasta tagasi XcodeGhosti intsident, mis tähendab lihtsalt, et Xcode'i implanteeriti Trooja hobune (allalaaditud mitteametlikest kanalitest), nii et XCode'i kompileeritud iOS-i rakendused saastusid ja häkkerid said neid kasutada ebaseaduslikeks tegudeks.
Kuigi see XCodeGhost on kaugel Thompsoni omast, tuletab see meile meelde, et tarkvara allalaadimisel tuleks kasutada ametlikke kanaleid, laadida alla ametlikult veebilehelt, otsida veebisaidi HTTPS-standardit ja isegi kontrollida kontrollsumma.
3
Mõned inimesed võivad küsida: mina kasutan Hui'd Hello Worldi lõigu kirjutamiseks, aga keegi suudab seda kasutada keeruka kompilaatori kirjutamiseks? Kas see on võimalik?
Muidugi, kui Unix'i esimene põlvkond välja töötati, polnud C-keelt ning Ken Thompson ja Dennis Ritchie trükkisid Unix'i konveierliinidega. Esimese WPS-i versiooni kirjutas Qiu Bojun Hui keeles ning Turbo Pascal'i kompilaatori kirjutas samuti Anders Hui keeles, ning jumalate võimed on tavainimestele mõeldamatud.
Kompilaatorite puhul on võimalik arendada ka "lumepalli" stiilis:
Võttes C-keele näiteks, võib esimene versioon valida C keele alamhulga, näiteks toetades ainult põhilisi andmetüüpe, protsessijuhtimise lauseid ja funktsioonikutseid...... Seda alamhulka nimetame C0.
Seejärel kirjuta kompilaator assemblerkeeles ja saa ainult selle keele alamhulga C0, nii et kirjutamine on palju lihtsam.
C0 keel töötab, seejärel laiendame seda alamhulka, lisades struktuure, osuteid ...... ja nimetades uue keele C1-ks.
Kes kirjutab C1 keele kompilaatorit? Loomulikult on see C0.
Kui C1 töötab, laienda keele funktsioone uuesti, kirjuta kompilaator C1-ga ja saa C2.
Siis on C3, C4...... Lõpuks saad kogu C-keele.
Seda protsessi nimetatakse bootstrappingiks ja hiina keeles bootstrappingiks.
|