[Powered by Google Translate] ROB BOWDEN: Porozmawiajmy o kompilatory.
Do tego momentu, właśnie wpisałeś swój kod źródłowy do
niektóre pliki, wysłał je przez tego wielkiego czarnej skrzynki, która jest
Dzyń, a obecnie jest plik wykonywalny, który nie
dokładnie to, co napisałem w kodzie źródłowym.
Jak magiczne jak było, jedziemy do podjęcia bliżej
patrzeć na to, co faktycznie dzieje się
kiedy skompilować plik.
Więc co to znaczy, aby skompilować coś?
>> No cóż, w najbardziej ogólnym sensie, to tylko oznacza
kod napisany w jednym przekształcania
języka programowania na inny.
Ale zwykle, gdy ludzie mówią, że coś skompilować, to
znaczy, że bierzesz to z wyższego poziomu programowania
język do niższego poziomu języka programowania.
To może wydawać się sposób bardzo subiektywne.
Na przykład, to prawdopodobnie nie myśleć o C, jak wysoki
język programowania, poziom, ale można go skompilować.
Ale to wszystko jest względne.
Jak zobaczymy, kod montaż i ostatecznie maszyna
Kod, który możemy skompilować dół jest niezaprzeczalnie niższy poziom
niż C.
Chociaż będziemy używać brzękiem w dzisiejszej demonstracji
Wiele z pomysłów tutaj przenieść do innych kompilatorów.
>> Dla Clang, istnieją cztery główne etapy ogólna
kompilacji.
Są to jedno, przerób wykonane przez preprocesor, dwa,
Opracowanie wykonane przez kompilator, trzy, montaż
dokonana przez montera, i cztery,
łączenie robione przez linker.
Może to być mylące, że jednym z podkroki ogólnej
Kompilatory dzyń nazywa kompilator, ale
dojdziemy do tego.
Będziemy używać proste Hello World w naszym przykładzie
przez cały ten film.
Rzućmy okiem.
>> Pierwszym krokiem jest przerób.
Co preprocesor zrobić?
W prawie każdym programie C kiedykolwiek przeczytać lub pisemne,
użyłeś linii kodu, które zaczynają się od mieszania.
Ja nazywam to hash, ale można również nazwać funtów, numer
podpisania, lub ostry.
Każda taka linia jest Dyrektywa preprocesora.
Prawdopodobnie widziałeś # define i # include przed, ale nie
kilka bardziej, że preprocesor uznaje.
Dodajmy # define do naszego powitania przykład światowej.
Teraz uruchom tylko preprocesor na tym pliku.
Przekazując CLAGE flagi-E, jesteś pouczając go uruchomić
tylko preprocesor.
Zobaczmy, co się dzieje.
To wygląda jak Clang tylko wypluwa wszystko
w wierszu poleceń.
Aby zapisać wszystkie tego wyjścia do nowego pliku o nazwie
hello2.c będziemy dołączać> hello2.c do naszej komendy.
Teraz rzućmy okiem na nasz przetworzonej pliku.
>> Whoa, co stało się z naszego krótkiego małego programu?
Jeśli idziemy aż do końca pliku, zobaczymy
część kodu, że rzeczywiście napisał.
Zauważ, że # define nie ma, a wszystkie wystąpienia nazwy
zostały zastąpione dokładnie to, co określono w
# define linię.
Więc jakie są te wszystkie typedef i deklaracje funkcji
na początku pliku?
Zauważ, że # define nie tylko preprocesor
dyrektywa, że ​​określona.
Mamy też # include stdio.h.
Więc wszystkie szalone linie są właściwie tylko stdio.h kopiowane
i wkleić na górze tego pliku.
Dlatego pliki nagłówkowe są przydatne dla funkcji
deklaracje.
Zamiast konieczności kopiowania i wklejania wszystkich funkcji
Deklaracje planujesz używać na górze pliku,
preprocesor będzie skopiować i wkleić je z nagłówka
plik dla Ciebie.
>> Teraz, kiedy skończyliśmy wstępne przetwarzanie, ruszamy na
kompilacji.
Powodem nazywamy to kompilacja krokiem jest, ponieważ jest to
Krok, w którym faktycznie musi Clang jego kompilacji z C do
Kod montaż.
Aby mieć Clang skompilować plik w dół do montażu, ale
kontynuować dalej, przekazać ją flag-S
w wierszu poleceń.
Rzućmy okiem na zgromadzeniu
plik był wyprowadzany.
To wygląda jak całkiem inny język.
Kod Montaż jest bardzo procesor specyficzne.
W tym przypadku, ponieważ CS50 urządzenie pracuje na
wirtualny procesor x86, x86 to kod montaż.
Bardzo niewielu ludzi pisać bezpośrednio w kodzie asemblera te dni,
ale każdy program C kiedykolwiek napisać zostaje przekształcona w dół
do montażu.
Ponownie wzywamy ten krok kompilujesz C do montażu
ponieważ będą z wyższego poziomu na niższy poziom
języka programowania.
>> Co sprawia, że ​​montaż niższym poziomie niż C?
Cóż, w zespole, mamy bardzo ograniczony w tym, co możemy zrobić.
Nie ma w razie, podczas gdy jest, za to, czy pętle jakiegokolwiek rodzaju.
Ale można osiągnąć te same rzeczy, które ich kontrola
konstrukcje oferują przy ograniczonych operacji, które
Zespół ma zapewnić.
Ale żeby zobaczyć, jak niski poziom naprawdę jest montaż, chodźmy
kolejny krok w naszym zestawieniu, montaż.
To assembler Zadaniem przekształcenie kodu assemblera
do obiektu lub kodu maszynowego.
Pamiętaj, że assembler nie zespół wyjściowego;
raczej, trwa w montażu i kodu maszynowego wyjść.
Kod maszynowy jest rzeczywisty 1 i 0, że CPU może
rozumiem, choć mamy jeszcze odrobinę pracy lewo
przed możemy uruchomić nasz program.
Miejmy wykonujemy nasze kodu assemblera przechodząc
-C Clang flag.
Teraz zobaczmy, co jest w zmontowanym pliku.
>> Dobrze, że nie pomoże nam bardzo.
Pamiętaj, że kod maszynowy jest zer i jedynek, że
Twój komputer może zrozumieć.
To nie znaczy, że to łatwe dla nas do zrozumienia.
Tak dokładnie, jak niski poziom jest montaż?
Jest prawie identyczny z kodem wynikowym.
Idąc od montażu do kodu wynikowego jest o wiele więcej
Tłumaczenie niż transformacji, dlatego
nikt nie może wziąć pod uwagę, aby assembler
nie wykonują żadnej kompilacji.
W rzeczywistości, jest to dość łatwe do ręcznie przetłumaczyć z
montaż do kodu maszynowego.
Patrząc na składzie dla głównej funkcji, że pierwsza linia
zdarza się odpowiadać szesnastkowych 0x55.
W formacie binarnym, to 1010101.
Druga linia trafem odpowiada szesnastkową 0x895.
I następna, 0x56.
Biorąc pod uwagę stosunkowo prosty stół, można tłumaczyć
montaż do kodu, że maszyny mogą zrozumieć też.
>> Więc jest jeden krok w pozostałych
kompilacji, który łączący.
Powiązanie łączy kilka plików obiektów w jeden duży plik
że rzeczywiście można wykonać.
Łączenie jest bardzo zależna od systemu.
Więc Najłatwiej dostać brzękiem po prostu połączyć obiekt
pliki razem jest wywołanie brzękiem na wszystkie pliki, które
chcesz połączyć ze sobą.
Jeśli podasz. Plików Ó, to nie trzeba będzie ponownie przetworzyć,
kompilacji i montaż wszystkich kodu źródłowego.
Chodźmy rzucić funkcji matematycznej do naszego archiwum, więc mamy
coś łączyć w.
Teraz go skompilować z powrotem do kodu obiektu i
zadzwoń brzękiem na nim.
Ups.
Ponieważ zawierał funkcji matematycznej, musimy połączyć w
biblioteka matematyczna z-lm.
>> Jeśli chcemy połączyć ze sobą kilka. Pliki o że
napisał na nasz własny, że po prostu podać je wszystkie
linii poleceń.
Ograniczenie to, że tylko jeden z tych plików musi
faktycznie określić główną funkcję, albo
wykonywalny wynikające nie wiem od czego zacząć
działa kod.
Jaka jest różnica między określenia plik połączyć w
z-l, a po prostu określenia plik bezpośrednio?
Nic.
Tyle tylko, że dzieje się Clang dokładnie wiedzieć, co plik
like-lm coś dzieje się odwoływać.
Gdybyś wiedział, że plik się, można określić ją
jawnie.
Wystarczy pamiętać, że wszystko-l flag musiał przyjść na koniec
swojego zapotrzebowania klienta.
>> I to wszystko, co jest do niej.
Po prostu uruchom brzękiem na niektórych plików, to co to jest
rzeczywiście robi.
Nazywam się Rob Bowden, a to CS50.