[Powered by Google Translate] Rob Bowden: La oss snakke om kompilatorer. Frem til dette punktet, har du nettopp skrev opp kildekoden til noen filer, sendte dem gjennom denne store svarte boksen som er Clang, og kommer ut kjørbar fil som gjør nøyaktig hva du skrev i kildekoden. Så magisk som det har vært, skal vi ta en nærmere se på hva som faktisk skjer når vi kompilere en fil. Så hva betyr det å kompilere noe? Vel, i den mest generelle forstand, det betyr bare transformere kode skrevet i ett programmeringsspråk til et annet. Men vanligvis når folk sier de kompilere noe, de mener de tar det fra et høyere nivå programmering språk til et lavere nivå programmeringsspråk. Disse kan virke som svært subjektive vilkår. For eksempel, har du sannsynligvis ikke tenke på C som en høy programmeringsspråk, men du kompilere den. Men det er alle forhold. Som vi vil se, forsamlingen koden og til slutt maskin kode som vi kompilere ned til er unektelig et lavere nivå enn C. Selv om vi skal bruke Clang i dagens demonstrasjon, en Mange av ideene her bære over til andre kompilatorer. For Clang det fire hovedtrinn i den samlede kompilering. Disse er en, preprosessering gjort av preprosessor, to, kompilering gjort av kompilatoren, tre, montering gjort av montøren, og fire, lenking gjort av linkeren. Det kan være forvirrende at en av de i den generelle substeps Clang kompilatorer kalles kompilatoren, men vi får til det. Vi skal bruke en enkel hello world program som vårt eksempel gjennom denne videoen. La oss ta en titt. Det første trinnet er forbehandling. Hva gjør den preprosessor? I ganske mye hver C program du noensinne har lest eller skrevet, du har brukt linjer med kode som begynner med en hash. Jeg vil kalle det hasj, men du kan også kalle det pounds, antall signere, eller skarp. Enhver slik linje er en preprosessor-direktiv. Du har sikkert sett # define og # include før, men det er flere mer at preprosessor gjenkjenner. La oss legge til et # define til vår hello world eksempel. Nå la oss kjøre bare preprosessor på denne filen. Ved å sende clage-E flagget, du instruksjoner om å kjøre bare preprosessor. La oss se hva som skjer. Det ser ut som Clang bare spytter ut alt på kommandolinjen. For å lagre alle av denne produksjonen til en ny fil som heter hello2.c, vil vi legge> hello2.c til kommandoen. La oss nå ta en titt på vår preprocessed fil. Jøss, skjedde det til vår korte lille programmet? Hvis vi går hele veien ned til bunnen av denne filen, vil vi se noen av koden at vi faktisk skrev. Legg merke til at # define er borte og alle forekomster av navn har blitt erstattet med nøyaktig hva vi angitt i den # define linjen. Så hva er alle disse typedefs og funksjon erklæringer øverst filen? Legg merke til at # define var ikke den eneste preprosessor direktiv som vi angitt. Vi har også # include stdio.h. Så alle de sprø linjene er faktisk bare stdio.h kopiert og limes inn i toppen av denne filen. Det er derfor header filer er så nyttig for funksjon erklæringer. I stedet for å måtte kopiere og lime inn alle funksjonen erklæringer du planlegger å bruke på toppen av filen, de preprosessor vil kopiere og lime dem fra topp fil for deg. Nå som vi er ferdig forbehandling, beveger vi oss inn på kompilering. Grunnen til at vi kaller dette trinnet samlealbum er fordi dette er trinnet der Clang faktisk gjør sin kompilering fra C til assemblykode. For å ha Clang kompilere en fil ned til montering, men fortsette lenger, passerer den-S flagget på kommandolinjen. La oss ta en titt på forsamlingen filen som ble generert. Det ser ut som en helt annen språk. Assemblykode er svært prosessor spesifikk. I dette tilfellet, siden CS50 apparatet kjører på en virtuell x86-prosessor, er dette x86 assembly kode. Svært få mennesker skrive direkte i assembly-kode i disse dager, men hver C-program du noen gang skriver blir transformert ned i forsamlingen. Igjen, vi kaller dette trinnet kompilere den C i forsamlingen siden vi kommer fra et høyere nivå til et lavere nivå programmeringsspråk. Hva gjør monteringen lavere nivå enn C? Vel, i forsamlingen, er vi svært begrenset hva vi kan gjøre. Det er ingen If, mens tallet, for er, eller løkker av noe slag. Men du kan oppnå de samme tingene som disse kontroll strukturer tilby hjelp de begrensede operasjoner som montering gjør gi. Men bare for å se hvor lavt nivå montering egentlig er, la oss gå ett skritt videre i samlingen vår, montering. Det er assembler jobb å transformere assemblerkode inn objekt eller maskinkode. Husk at assembler ikke kan sende montering; heller, det tar i montering og utganger maskinkode. Maskinkode er den faktiske 1 og 0-er som en CPU kan forstå, selv om vi fortsatt har en liten bit av arbeid igjen før vi kan kjøre programmet vårt. La oss sammen vår assemblykode ved å sende Clang-c flagget. La oss nå se hva som er i den sammensatte filen. Vel, som ikke hjelper oss veldig mye. Husk at maskinen koden er de enere og nuller som datamaskinen kan forstå. Det betyr ikke at det er lett for oss å forstå. Så nøyaktig hvor lavt nivå er montering? Det er nesten identisk med objektkode. Går fra forsamlingen til objektkode er mye mer av en oversettelse enn en transformasjon, som er grunnen til at man kan ikke vurdere assembler for å gjøre noe faktisk kompilering. Faktisk er det ganske lett å manuelt oversette fra montering til maskinkode. Ser på forsamlingen for en hovedfunksjon, som første linje skjer tilsvare heksadesimale 0x55. I binær, det er 1010101. Den andre linjen skjer å korrespondere heksadesimale 0x895. Og den neste, 0x56. Gitt en relativt enkel tabell, kan du oversette montering i koden som maskinene kan oppfatte også. Så det er en gjenværende skritt i kompilering, som er knytte. Linking kombinerer en haug med objekt-filer til én stor fil at du faktisk kan utføre. Linking er svært avhengig av systemet. Så den enkleste måten å få Clang å bare koble objekt filene sammen er å ringe Clang på alle filene som du vil koble sammen. Hvis du angir. O-filer, så det trenger ikke å behandle, kompilere og sette sammen alle kildekoden. La oss kaste et matematisk funksjon i filen vår, så vi har noe å knytte i. La oss nå samle den tilbake ned til objektkode og kaller Clang på den. Oops. Siden vi inkludert en matte funksjon, må vi koble inn regnestykket biblioteket med-lm. Hvis vi ønsket å knytte sammen haug med. O filer som vi skrev på vår egen, ville vi bare spesifisere dem alle på kommandolinjen. Begrensningen er at bare en av disse filene must faktisk angi en hovedfunksjon, ellers resulterer kjørbar ville ikke vite hvor du skal begynne kjører koden din. Hva er forskjellen mellom å angi en fil for å koble inn med-l og bare spesifisere en fil direkte? Ingenting. Det er bare det at Clang skjer for å vite nøyaktig hva filen noe som-LM skjer å referere til. Hvis du visste at filen selv, kan du angi det eksplisitt. Bare husk at all-l flagg må komme på slutten av din klient etterspørsel. Og det er alt som skal til. Når du bare kjøre Clang på noen filer, dette er hva det er faktisk gjør. Mitt navn er Rob Bowden, og dette er CS50.