1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROB BOWDEN: Lassen Sie uns über Compiler sprechen. 2 00:00:09,100 --> 00:00:11,490 Bis zu diesem Punkt haben Sie gerade Ihren Quelltext eingegeben in 3 00:00:11,490 --> 00:00:14,260 einige Dateien, schickte sie durch diese großen schwarzen Box, die ist 4 00:00:14,260 --> 00:00:16,890 Clang, und heraus kommt die ausführbare Datei, die funktioniert 5 00:00:16,890 --> 00:00:19,430 genau das, was Sie geschrieben haben in Ihrem Quellcode. 6 00:00:19,430 --> 00:00:22,170 So magisch wie die gewesen ist, werden wir einen genaueren 7 00:00:22,170 --> 00:00:23,590 schauen, was tatsächlich passiert 8 00:00:23,590 --> 00:00:25,220 wenn wir kompilieren eine Datei. 9 00:00:25,220 --> 00:00:28,580 Also, was bedeutet es, etwas zu kompilieren? 10 00:00:28,580 --> 00:00:31,150 >> Nun, in einem sehr allgemeinen Sinn, es bedeutet nur, 11 00:00:31,150 --> 00:00:32,580 Umwandlung Code in einer schriftlichen 12 00:00:32,580 --> 00:00:34,680 Programmiersprache zur anderen. 13 00:00:34,680 --> 00:00:37,550 Aber in der Regel, wenn die Leute sagen, dass sie zu kompilieren etwas, sie 14 00:00:37,550 --> 00:00:39,660 bedeuten sie nehmen es von einer höheren Ebene Programmierung 15 00:00:39,660 --> 00:00:42,460 Sprache auf einem niedrigeren Niveau Programmiersprache. 16 00:00:42,460 --> 00:00:44,960 Diese können wie sehr subjektiv sein. 17 00:00:44,960 --> 00:00:48,090 Zum Beispiel werden Sie wahrscheinlich nicht von C denken, wie einer hohen 18 00:00:48,090 --> 00:00:51,440 Level-Programmiersprache, aber Sie wissen es zu kompilieren. 19 00:00:51,440 --> 00:00:52,730 Aber es ist alles relativ. 20 00:00:52,730 --> 00:00:55,790 Wie wir sehen werden, die Assembler-Code und schließlich Maschine 21 00:00:55,790 --> 00:00:59,270 Code, den wir unten zu kompilieren ist zweifellos ein niedrigeres Niveau 22 00:00:59,270 --> 00:01:00,700 als C. 23 00:01:00,700 --> 00:01:03,310 Obwohl wir mit werden Clang in der heutigen Demonstration, 24 00:01:03,310 --> 00:01:06,360 Viele der Ideen, die hier übertragen auf anderen Compilern. 25 00:01:06,360 --> 00:01:09,160 >> Für Clang gibt es vier Hauptschritte im Gesamtsystem 26 00:01:09,160 --> 00:01:10,200 Zusammenstellung. 27 00:01:10,200 --> 00:01:15,430 Dies sind ein, Vorverarbeitung durch den Präprozessor getan, zwei, 28 00:01:15,430 --> 00:01:19,530 Zusammenstellung durch den Compiler getan, drei, Montage 29 00:01:19,530 --> 00:01:22,010 getan vom Assembler und vier, 30 00:01:22,010 --> 00:01:24,640 Verknüpfung vom Linker getan. 31 00:01:24,640 --> 00:01:27,600 Es kann verwirrend sein, dass einer der Unterschritte des Gesamtsystems 32 00:01:27,600 --> 00:01:30,980 Clang Compiler wird als Compiler, sondern 33 00:01:30,980 --> 00:01:32,530 wir dazu kommen. 34 00:01:32,530 --> 00:01:35,050 Wir werden mit einem einfachen Hallo Welt Programm als Beispiel 35 00:01:35,050 --> 00:01:36,270 in diesem video. 36 00:01:36,270 --> 00:01:38,380 Lassen Sie uns einen Blick. 37 00:01:38,380 --> 00:01:40,330 >> Der erste Schritt ist Vorverarbeitung. 38 00:01:40,330 --> 00:01:42,520 Was macht der Präprozessor tun? 39 00:01:42,520 --> 00:01:45,560 In so ziemlich jedem C Programm, das Sie je gelesen habe oder schriftlicher Form 40 00:01:45,560 --> 00:01:48,310 Sie haben Codezeilen, die mit einem Hash beginnen verwendet. 41 00:01:48,310 --> 00:01:51,730 Ich nenne es Hash, aber man kann auch sagen Pfund, Anzahl 42 00:01:51,730 --> 00:01:53,280 Anmeldung oder scharf. 43 00:01:53,280 --> 00:01:56,840 Eine solche Linie ist eine Präprozessordirektive. 44 00:01:56,840 --> 00:02:00,650 Sie haben wahrscheinlich gesehen # define und # vor beinhalten, aber es 45 00:02:00,650 --> 00:02:03,690 gibt mehrere, die der Präprozessor erkennt. 46 00:02:03,690 --> 00:02:07,340 Fügen wir eine # unsere Hallo Welt Beispiel definieren. 47 00:02:07,340 --> 00:02:11,690 Jetzt lasst uns laufen nur den Präprozessor auf diese Datei. 48 00:02:11,690 --> 00:02:16,150 Durch die Übergabe Clage the-E-Flag, Sie anweist, zu laufen 49 00:02:16,150 --> 00:02:17,880 nur der Präprozessor. 50 00:02:17,880 --> 00:02:19,130 Mal sehen, was passiert. 51 00:02:22,250 --> 00:02:24,020 Es sieht aus wie Clang nur spuckt alles 52 00:02:24,020 --> 00:02:25,200 auf der Kommandozeile. 53 00:02:25,200 --> 00:02:27,800 Um all diese Ausgabe in eine neue Datei namens sparen 54 00:02:27,800 --> 00:02:33,850 hello2.c, wir anhängen> hello2.c auf unseren Befehl. 55 00:02:33,850 --> 00:02:37,800 Werfen wir nun einen Blick auf unsere vorverarbeiteten Datei. 56 00:02:37,800 --> 00:02:40,810 >> Whoa, passiert was unsere kurze kleines Programm? 57 00:02:40,810 --> 00:02:43,890 Wenn wir alle den Weg zum Ende der Datei zu gehen, werden wir sehen, 58 00:02:43,890 --> 00:02:46,070 Teil des Codes, dass wir tatsächlich schrieb. 59 00:02:46,070 --> 00:02:49,800 Beachten Sie, dass der # define-gegangen ist und alle Instanzen des Namens 60 00:02:49,800 --> 00:02:51,950 haben genau das, was wir in festgelegten ersetzt worden 61 00:02:51,950 --> 00:02:53,590 der # define-Zeile. 62 00:02:53,590 --> 00:02:56,530 Also, was sind alle diese typedefs und Funktionsdeklarationen 63 00:02:56,530 --> 00:02:58,140 am Anfang der Datei? 64 00:02:58,140 --> 00:03:00,820 Beachten Sie, dass der # define war nicht der einzige Präprozessor 65 00:03:00,820 --> 00:03:02,390 Richtlinie, die wir angegeben. 66 00:03:02,390 --> 00:03:05,280 Wir haben auch # include stdio.h. 67 00:03:05,280 --> 00:03:09,560 Also alle die verrückten Linien sind eigentlich nur stdio.h kopiert 68 00:03:09,560 --> 00:03:11,810 und in den Anfang der Datei eingefügt. 69 00:03:11,810 --> 00:03:14,110 Das ist, warum Header-Dateien so nützlich für die Funktion sind 70 00:03:14,110 --> 00:03:15,160 Deklarationen. 71 00:03:15,160 --> 00:03:17,740 Statt benötigen zum Kopieren und Einfügen all der Funktion 72 00:03:17,740 --> 00:03:21,050 Deklarationen über die Verwendung am Anfang der Datei, die 73 00:03:21,050 --> 00:03:22,990 Präprozessor kopieren und sie aus dem Header 74 00:03:22,990 --> 00:03:24,140 Datei für Sie. 75 00:03:24,140 --> 00:03:26,480 >> Jetzt, da wir Vorverarbeitung fertig sind, bewegen wir uns auf 76 00:03:26,480 --> 00:03:27,680 Zusammenstellung. 77 00:03:27,680 --> 00:03:30,725 Der Grund nennen wir diesen Schritt Zusammenstellung ist, denn dies ist 78 00:03:30,725 --> 00:03:34,130 der Schritt, wo Clang eigentlich seine Kompilieren nicht von C nach 79 00:03:34,130 --> 00:03:35,370 Assembler-Code. 80 00:03:35,370 --> 00:03:38,280 Um über Clang kompiliert eine Datei auf Montage, aber 81 00:03:38,280 --> 00:03:42,030 weiterhin nicht weiter, geben sie dem Flag-s 82 00:03:42,030 --> 00:03:43,560 auf der Kommandozeile. 83 00:03:43,560 --> 00:03:44,790 Werfen wir einen Blick auf die Montage 84 00:03:44,790 --> 00:03:47,390 Datei, die ausgegeben wurde. 85 00:03:47,390 --> 00:03:49,740 Es sieht aus wie eine ganz andere Sprache. 86 00:03:49,740 --> 00:03:52,660 Assembly-Code ist sehr Prozessor-spezifischen. 87 00:03:52,660 --> 00:03:55,440 In diesem Fall, da die CS50 Gerät ist auf eine laufende 88 00:03:55,440 --> 00:04:00,470 virtuellen x86-Prozessor, ist dies x86-Assembler-Code. 89 00:04:00,470 --> 00:04:03,450 Sehr wenige Menschen schreiben Sie direkt in Assembler-Code in diesen Tagen, 90 00:04:03,450 --> 00:04:06,490 aber jedes C Programm, das Sie jemals schreiben transformiert wird unten 91 00:04:06,490 --> 00:04:07,940 in der Montage. 92 00:04:07,940 --> 00:04:11,440 Wieder nennen wir diesen Schritt der Erstellung des C in Assembler 93 00:04:11,440 --> 00:04:14,170 da es sich von einem höheren Niveau auf ein niedrigeres Niveau gehen 94 00:04:14,170 --> 00:04:15,480 Programmiersprache. 95 00:04:15,480 --> 00:04:17,880 >> Was macht die Montage niedrigeren Niveau als C? 96 00:04:17,880 --> 00:04:21,660 Nun, in der Montage, sind wir sehr in dem, was wir tun können, begrenzt. 97 00:04:21,660 --> 00:04:25,120 Es gibt keine, wenn das, während es für ist, oder Schleifen jeglicher Art. 98 00:04:25,120 --> 00:04:27,560 Aber man kann erreichen, die gleichen Dinge, dass diese Kontrolle 99 00:04:27,560 --> 00:04:30,270 Strukturen bieten die begrenzten Operationen, 100 00:04:30,270 --> 00:04:32,350 Montage vorsieht. 101 00:04:32,350 --> 00:04:35,960 Aber zu sehen, wie niedrige Montage wirklich ist, gehen wir 102 00:04:35,960 --> 00:04:39,320 einen weiteren Schritt in unserer Zusammenstellung, Montage. 103 00:04:39,320 --> 00:04:41,890 Es ist der Assembler die Aufgabe, die Assembler-Code zu transformieren 104 00:04:41,890 --> 00:04:44,740 in das Objekt oder Maschinencode. 105 00:04:44,740 --> 00:04:47,610 Beachten Sie, dass der Monteur nicht der Output Assembly; 106 00:04:47,610 --> 00:04:51,080 statt, dauert es in der Montage-und Ausgänge Maschinencode. 107 00:04:51,080 --> 00:04:54,040 Maschinen-Code ist die eigentliche 1 und 0, dass eine CPU 108 00:04:54,040 --> 00:04:57,290 verstehen, obwohl wir immer noch ein klein wenig Arbeit verlassen 109 00:04:57,290 --> 00:04:59,380 bevor wir laufen unserem Programm. 110 00:04:59,380 --> 00:05:01,400 Lassen Sie montieren unsere Assembler-Code, indem 111 00:05:01,400 --> 00:05:04,080 Clang-c-Flag. 112 00:05:04,080 --> 00:05:06,410 Nun wollen wir sehen, was in dem zusammengebauten Datei. 113 00:05:06,410 --> 00:05:09,220 >> Nun, das nicht hilft uns sehr. 114 00:05:09,220 --> 00:05:11,340 Beachten Sie, dass der Maschinencode die Einsen und Nullen, dass es 115 00:05:11,340 --> 00:05:13,240 Computer verstehen kann. 116 00:05:13,240 --> 00:05:16,080 Das bedeutet nicht, es ist einfach für uns zu verstehen. 117 00:05:16,080 --> 00:05:19,160 So genau, wie niedrig ist die Montage? 118 00:05:19,160 --> 00:05:21,480 Es ist fast identisch mit Objekt-Code. 119 00:05:21,480 --> 00:05:24,300 Gehen von der Montage bis Objekt-Code ist viel mehr ein 120 00:05:24,300 --> 00:05:27,540 Übersetzung als eine Transformation, weshalb 121 00:05:27,540 --> 00:05:29,310 könnte man nicht der Ansicht, die Assembler 122 00:05:29,310 --> 00:05:31,400 noch keine tatsächliche Kompilierung. 123 00:05:31,400 --> 00:05:34,110 In der Tat ist es ziemlich einfach, manuell übersetzen 124 00:05:34,110 --> 00:05:36,050 Montage in Maschinencode. 125 00:05:36,050 --> 00:05:39,040 Mit Blick auf die Anordnung für eine Hauptfunktion, dass erste Zeile 126 00:05:39,040 --> 00:05:42,100 geschieht in hexadezimal 0x55 entsprechen. 127 00:05:42,100 --> 00:05:45,470 In binären, das ist 1010101. 128 00:05:45,470 --> 00:05:49,300 Die zweite Zeile passiert Hexadezimal 0x895 entsprechen. 129 00:05:49,300 --> 00:05:51,290 Und das nächste, 0x56. 130 00:05:51,290 --> 00:05:53,730 Angesichts einer relativ einfache Tabelle, könnte man übersetzen 131 00:05:53,730 --> 00:05:57,130 Montage in dem Code, den Maschinen zu verstehen. 132 00:05:57,130 --> 00:05:58,810 >> So gibt es eine verbleibende Schritt in 133 00:05:58,810 --> 00:06:01,150 Zusammenstellung, die Verknüpfen. 134 00:06:01,150 --> 00:06:04,530 Verknüpfung kombiniert eine Reihe von Objekt-Dateien in eine große Datei 135 00:06:04,530 --> 00:06:06,380 dass Sie tatsächlich auszuführen. 136 00:06:06,380 --> 00:06:08,570 Verlinkung ist sehr abhängig vom Betriebssystem. 137 00:06:08,570 --> 00:06:11,030 Der einfachste Weg, um Clang werde dann verknüpfen Objekt 138 00:06:11,030 --> 00:06:13,920 Dateien zusammen zu Clang auf alle Dateien, die rufen 139 00:06:13,920 --> 00:06:15,190 Sie miteinander zu verknüpfen. 140 00:06:15,190 --> 00:06:18,740 Wenn Sie. Geben o-Dateien, dann wird es nicht erneut zu verarbeiten müssen, 141 00:06:18,740 --> 00:06:21,680 kompilieren, und montieren alle Ihre Source-Code. 142 00:06:21,680 --> 00:06:23,960 Werfen wir einen mathematischen Funktion in unserer Datei, so haben wir 143 00:06:23,960 --> 00:06:25,210 etwas zu verknüpfen in. 144 00:06:34,220 --> 00:06:37,010 Nun wollen wir es kompilieren wieder auf Objekt-Code und 145 00:06:37,010 --> 00:06:38,260 rufen Clang auf sie. 146 00:06:40,560 --> 00:06:41,420 Oops. 147 00:06:41,420 --> 00:06:43,790 Da wir eine mathematische Funktion enthalten, müssen wir in verlinken 148 00:06:43,790 --> 00:06:46,610 die Mathematik-Bibliothek mit-lm. 149 00:06:46,610 --> 00:06:48,990 >> Wenn wir miteinander zu verknüpfen Haufen wollte. O Dateien, die wir 150 00:06:48,990 --> 00:06:51,420 schrieb am eigenen, würden wir nur angeben, sie alle auf die 151 00:06:51,420 --> 00:06:52,460 Befehlszeile. 152 00:06:52,460 --> 00:06:55,320 Die Einschränkung ist, dass nur eine dieser Dateien müssen 153 00:06:55,320 --> 00:06:57,790 tatsächlich geben Sie eine Hauptfunktion, da sonst die 154 00:06:57,790 --> 00:06:59,930 resultierende ausführbare Datei würde nicht wissen, wo ich anfangen soll 155 00:06:59,930 --> 00:07:00,910 Ihren Code ausführen. 156 00:07:00,910 --> 00:07:03,360 Was ist der Unterschied zwischen der Angabe einer Datei in verlinken 157 00:07:03,360 --> 00:07:06,600 mit-l und nur die Angabe einer Datei direkt? 158 00:07:06,600 --> 00:07:07,440 Nichts. 159 00:07:07,440 --> 00:07:09,850 Es ist nur so, dass Clang genau das, was Datei kennen passiert 160 00:07:09,850 --> 00:07:12,560 so etwas wie-lm Fall zu beziehen. 161 00:07:12,560 --> 00:07:14,700 Wenn Sie diese Datei wussten Sie, können Sie angeben, es 162 00:07:14,700 --> 00:07:15,930 ausdrücklich. 163 00:07:15,930 --> 00:07:18,990 Denken Sie daran, dass all-l-Flags am Ende kommen müssen 164 00:07:18,990 --> 00:07:20,770 Ihrer Nachfrage der Kunden. 165 00:07:20,770 --> 00:07:22,300 >> Und das ist alles dort ist zu ihm. 166 00:07:22,300 --> 00:07:24,940 Wenn Sie gerade laufen Clang auf einige Dateien, das ist, was es ist 167 00:07:24,940 --> 00:07:26,350 eigentlich tun. 168 00:07:26,350 --> 00:07:29,490 Mein Name ist Rob Bowden, und dies ist CS50.