[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.