"În ce limbă este scris chiar C?"
Din altă perspectivă, este: înainte ca limbajul C să ruleze, trebuie compilat, deci de unde provine compilatorul limbajului C? În ce limbă este scris? Dacă este scris chiar cu C, există mai întâi un ou sau o găină?
1
Să presupunem că nu există compilatoare în lume, să începem cu limbajul mașinii și să vedem cum.
Limbajul mașina poate fi executat direct de CPU fără a fi nevoie de un compilator.
Apoi există limbajul de asamblare, deși limbajul de asamblare este doar un mnemonic pentru limbajul mașină, dar trebuie și compilat în limbaj mașină pentru a fi executat, deci nu există altă opțiune decât să folosești limbaj mașină pentru a scrie acest prim compilator (care nu va mai fi folosit în viitor).
Problema limbajului de asamblare este rezolvată și este un mare pas înainte; în acest moment este posibil să se folosească limbaj de asamblare pentru a scrie compilatorul în limbajul C, despre care spunem că este strămoșul compilatorului C.
Cu acest strămoș, poți compila orice program în limbaj C, deci poți scrie un compilator chiar în limbajul C? Doar compilați-l împreună cu strămoșii.
OK, după un astfel de strat, am reușit în sfârșit să am un compilator scris în C, ceea ce este foarte problematic.
În acest moment, compilatorul C scris de pachetul anterior poate fi abandonat.
Desigur, dacă au existat și alte limbaje de nivel înalt înainte de C, cum ar fi Pascal, atunci Pascal ar putea fi folosit pentru a scrie un compilator C.
Se spune că compilatorul primului Pascal a fost scris în Fortran. Fiind primul limbaj de nivel înalt, compilatorul lui Fortran ar trebui să fie scris în limbaj de asamblare.
2
Iată o legendă interesantă despre compilator:
Legenda spune că Ken Thompson, unul dintre inventatorii Unix, s-a îndrăznit pe orice mașină Unix de la Bell Labs, și-a introdus numele de utilizator și parola și putea să se conecteze în modul root!
Bell Labs este plin de talent, iar alți mari tauri au jurat să găsească această vulnerabilitate, au citit codul sursă C al Unix și în cele din urmă au găsit backdoor-ul de autentificare, iar după ce au curățat backdoor-ul, au compilat Unix și l-au rulat, dar Thompson a reușit totuși să se logheze.
Unii cred că ar putea exista o problemă cu compilatorul și că a fost implantată o ușă din spate la compilarea Unix, așa că au rescris un compilator în C și au compilat din nou Unix cu un nou compilator.
Dar tot nu funcționează, Thompson încă se poate conecta cu root, ceea ce este cu adevărat devastator!
Mai târziu, Thompson însuși a descoperit secretul, a fost primul compilator C care a avut o problemă, acest compilator va fi, desigur, implantat pe ușa din spate când compilezi codul sursă Unix, asta nu este suficient, și mai bine, dacă scrii un nou compilator în limbaj C, trebuie neapărat să-l compilezi în cod binar, ce să compilezi, folosește doar primul compilator scris de Thompson pentru compilare, bine, compilatorul pe care l-ai scris va fi poluat, compilatorul tău va compila din nou Unix, Voi implanta și o ușă din spate :-)
Apropo, îmi amintesc de incidentul XcodeGhost de acum câțiva ani, care înseamnă pur și simplu că un cal troian a fost implantat în Xcode (descărcat de pe canale neoficiale), astfel încât aplicațiile iOS compilate de XCode au fost contaminate, iar aceste aplicații ar putea fi folosite de hackeri pentru a face lucruri ilegale.
Deși acest XCodeGhost este departe de a fi al lui Thompson, ne amintește că atunci când descarci software, ar trebui să folosești canale formale, să descarci de pe site-ul oficial, să cauți standardul HTTPS al site-ului și chiar să verifici suma de control.
3
Unii oameni ar putea întreba: eu folosesc Hui pentru a scrie un paragraf Hello World, dar cineva îl poate folosi pentru a scrie un compilator complex? Este posibil așa ceva?
Desigur, când a fost dezvoltată prima generație de Unix, nu exista limbaj C, iar Ken Thompson și Dennis Ritchie scriau Unix cu linii de asamblare. Prima versiune a WPS a fost scrisă de Qiu Bojun în Hui, iar compilatorul lui Turbo Pascal a fost scris tot de Anders în Hui, iar abilitățile zeilor nu sunt imaginabile pentru oamenii obișnuiți.
Pentru compilatoare, este posibil și să se dezvolte într-un mod "bulgăre de zăpadă":
Luând totuși ca exemplu limbajul C, prima versiune poate alege un subset al limbajului C, cum ar fi să suporte doar tipuri de date de bază, instrucțiuni de control al procesului și apeluri de funcții...... Numim acest subset C0.
Apoi scrie un compilator în limbaj de asamblare și obții doar un subset al acestui limbaj C0, astfel încât să fie mult mai ușor de scris.
Limbajul C0 funcționează, iar apoi extindem acest subset adăugând structuri, pointeri ...... și numind noul limbaj C1.
Cine scrie compilatorul pentru limbajul C1? Desigur, este C0.
Când C1 funcționează, extinde din nou caracteristicile limbajului, scrie compilatorul cu C1 și obține C2.
Apoi sunt C3, C4...... În cele din urmă, primești limbajul complet C.
Acest proces se numește bootstrapping, iar în chineză se numește bootstrapping.
|