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