1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROB Bowden: Mari kita bicara tentang kompiler. 2 00:00:09,100 --> 00:00:11,490 Sampai titik ini, Anda baru saja mengetik kode sumber Anda ke 3 00:00:11,490 --> 00:00:14,260 beberapa file, mengirim mereka melalui kotak hitam besar yang 4 00:00:14,260 --> 00:00:16,890 Clang, dan keluar datang file eksekusi yang tidak 5 00:00:16,890 --> 00:00:19,430 apa yang Anda tulis dalam kode sumber Anda. 6 00:00:19,430 --> 00:00:22,170 Sebagai magis seperti itu sudah, kita akan mengambil lebih dekat 7 00:00:22,170 --> 00:00:23,590 melihat apa yang sebenarnya terjadi 8 00:00:23,590 --> 00:00:25,220 ketika kita mengkompilasi file. 9 00:00:25,220 --> 00:00:28,580 Jadi apa artinya untuk mengkompilasi sesuatu? 10 00:00:28,580 --> 00:00:31,150 >> Nah, dalam pengertian yang paling umum, itu hanya berarti 11 00:00:31,150 --> 00:00:32,580 mengubah kode yang ditulis dalam satu 12 00:00:32,580 --> 00:00:34,680 pemrograman bahasa ke bahasa lain. 13 00:00:34,680 --> 00:00:37,550 Tapi biasanya ketika orang mengatakan mereka mengkompilasi sesuatu, mereka 14 00:00:37,550 --> 00:00:39,660 berarti mereka mengambil dari pemrograman tingkat tinggi 15 00:00:39,660 --> 00:00:42,460 bahasa ke bahasa pemrograman tingkat yang lebih rendah. 16 00:00:42,460 --> 00:00:44,960 Ini mungkin tampak seperti hal yang sangat subjektif. 17 00:00:44,960 --> 00:00:48,090 Sebagai contoh, Anda mungkin tidak berpikir tentang C sebagai tinggi 18 00:00:48,090 --> 00:00:51,440 bahasa pemrograman tingkat, tetapi Anda compile. 19 00:00:51,440 --> 00:00:52,730 Tapi itu semua relatif. 20 00:00:52,730 --> 00:00:55,790 Seperti yang akan kita lihat, kode perakitan dan akhirnya mesin 21 00:00:55,790 --> 00:00:59,270 kode yang kita mengkompilasi ke tidak diragukan lagi tingkat yang lebih rendah 22 00:00:59,270 --> 00:01:00,700 dibandingkan C. 23 00:01:00,700 --> 00:01:03,310 Meskipun kami akan menggunakan dentang dalam demonstrasi hari ini, sebuah 24 00:01:03,310 --> 00:01:06,360 banyak ide di sini membawa ke kompiler lain. 25 00:01:06,360 --> 00:01:09,160 >> Untuk dentang, ada empat langkah utama dalam keseluruhan 26 00:01:09,160 --> 00:01:10,200 kompilasi. 27 00:01:10,200 --> 00:01:15,430 Ini adalah salah satu, preprocessing dilakukan oleh preprocessor, dua, 28 00:01:15,430 --> 00:01:19,530 kompilasi dilakukan oleh kompilator, tiga, perakitan 29 00:01:19,530 --> 00:01:22,010 dilakukan oleh assembler, dan empat, 30 00:01:22,010 --> 00:01:24,640 menghubungkan dilakukan oleh linker. 31 00:01:24,640 --> 00:01:27,600 Ini mungkin membingungkan bahwa salah satu substeps dari keseluruhan 32 00:01:27,600 --> 00:01:30,980 Kompiler clang disebut kompilator, namun 33 00:01:30,980 --> 00:01:32,530 kita akan mendapatkan bahwa. 34 00:01:32,530 --> 00:01:35,050 Kami akan menggunakan program sederhana halo dunia sebagai contoh kami 35 00:01:35,050 --> 00:01:36,270 seluruh video ini. 36 00:01:36,270 --> 00:01:38,380 Mari kita lihat. 37 00:01:38,380 --> 00:01:40,330 >> Langkah pertama adalah preprocessing. 38 00:01:40,330 --> 00:01:42,520 Apa preprocessor lakukan? 39 00:01:42,520 --> 00:01:45,560 Dalam hampir setiap program C Anda pernah membaca atau menulis, 40 00:01:45,560 --> 00:01:48,310 Anda telah menggunakan baris kode yang dimulai dengan hash. 41 00:01:48,310 --> 00:01:51,730 Saya akan menyebutnya hash, tetapi Anda juga dapat menyebutnya pound, jumlah 42 00:01:51,730 --> 00:01:53,280 menandatangani, atau tajam. 43 00:01:53,280 --> 00:01:56,840 Setiap baris tersebut adalah direktif preprocessor. 44 00:01:56,840 --> 00:02:00,650 Anda mungkin pernah melihat # define dan # include sebelumnya, tapi ada 45 00:02:00,650 --> 00:02:03,690 beberapa lagi yang preprocessor mengakui. 46 00:02:03,690 --> 00:02:07,340 Mari menambahkan # define untuk contoh dunia halo kami. 47 00:02:07,340 --> 00:02:11,690 Sekarang mari kita jalankan hanya preprocessor pada file ini. 48 00:02:11,690 --> 00:02:16,150 Dengan melewati bendera clage E-, Anda menginstruksikan untuk menjalankan 49 00:02:16,150 --> 00:02:17,880 hanya preprocessor. 50 00:02:17,880 --> 00:02:19,130 Mari kita lihat apa yang terjadi. 51 00:02:22,250 --> 00:02:24,020 Sepertinya dentang hanya meludah keluar semua 52 00:02:24,020 --> 00:02:25,200 pada baris perintah. 53 00:02:25,200 --> 00:02:27,800 Dalam rangka untuk menyimpan semua output ini ke file baru yang disebut 54 00:02:27,800 --> 00:02:33,850 hello2.c, kita akan tambahkan> hello2.c perintah kita. 55 00:02:33,850 --> 00:02:37,800 Sekarang mari kita lihat pada file preprocessed kami. 56 00:02:37,800 --> 00:02:40,810 >> Whoa, apa yang terjadi pada program pendek kecil kami? 57 00:02:40,810 --> 00:02:43,890 Jika kita pergi semua jalan ke bagian bawah file ini, kita akan melihat 58 00:02:43,890 --> 00:02:46,070 beberapa kode yang kita benar-benar menulis. 59 00:02:46,070 --> 00:02:49,800 Perhatikan bahwa # mendefinisikan hilang dan semua contoh nama 60 00:02:49,800 --> 00:02:51,950 telah diganti dengan apa yang kita ditentukan dalam 61 00:02:51,950 --> 00:02:53,590 # define baris. 62 00:02:53,590 --> 00:02:56,530 Jadi apa yang semua typedef dan deklarasi fungsi 63 00:02:56,530 --> 00:02:58,140 di bagian atas file? 64 00:02:58,140 --> 00:03:00,820 Perhatikan bahwa # define bukan hanya preprocessor 65 00:03:00,820 --> 00:03:02,390 direktif yang kita tentukan. 66 00:03:02,390 --> 00:03:05,280 Kami juga telah # include stdio.h. 67 00:03:05,280 --> 00:03:09,560 Jadi semua lini gila sebenarnya hanya stdio.h disalin 68 00:03:09,560 --> 00:03:11,810 dan disisipkan ke bagian atas file ini. 69 00:03:11,810 --> 00:03:14,110 Itulah sebabnya file header sangat berguna untuk fungsi 70 00:03:14,110 --> 00:03:15,160 deklarasi. 71 00:03:15,160 --> 00:03:17,740 Alih-alih perlu copy dan paste semua fungsi 72 00:03:17,740 --> 00:03:21,050 deklarasi Anda berencana untuk menggunakan di bagian atas file Anda, 73 00:03:21,050 --> 00:03:22,990 preprocessor akan copy dan paste mereka dari header 74 00:03:22,990 --> 00:03:24,140 mengajukan untuk Anda. 75 00:03:24,140 --> 00:03:26,480 >> Sekarang kita sudah selesai preprocessing, kita bergerak ke 76 00:03:26,480 --> 00:03:27,680 kompilasi. 77 00:03:27,680 --> 00:03:30,725 Alasan kita sebut ini kompilasi langkah ini karena ini adalah 78 00:03:30,725 --> 00:03:34,130 langkah mana dentang sebenarnya tidak kompilasi nya dari C ke 79 00:03:34,130 --> 00:03:35,370 perakitan kode. 80 00:03:35,370 --> 00:03:38,280 Dalam rangka untuk memiliki dentang mengkompilasi file ke perakitan, namun 81 00:03:38,280 --> 00:03:42,030 terus lagi, lulus S-flag 82 00:03:42,030 --> 00:03:43,560 pada baris perintah. 83 00:03:43,560 --> 00:03:44,790 Mari kita lihat pada perakitan 84 00:03:44,790 --> 00:03:47,390 file yang outputted. 85 00:03:47,390 --> 00:03:49,740 Sepertinya cukup bahasa yang berbeda. 86 00:03:49,740 --> 00:03:52,660 Kode assembly sangat prosesor yang spesifik. 87 00:03:52,660 --> 00:03:55,440 Dalam kasus ini, karena alat CS50 berjalan pada 88 00:03:55,440 --> 00:04:00,470 prosesor x86 virtual, ini adalah kode assembly x86. 89 00:04:00,470 --> 00:04:03,450 Sangat sedikit orang menulis langsung dalam kode assembly hari ini, 90 00:04:03,450 --> 00:04:06,490 namun setiap program C Anda pernah menulis akan berubah bawah 91 00:04:06,490 --> 00:04:07,940 dalam perakitan. 92 00:04:07,940 --> 00:04:11,440 Sekali lagi, kita sebut ini langkah kompilasi C ke assembly 93 00:04:11,440 --> 00:04:14,170 karena kita akan dari tingkat yang lebih tinggi ke tingkat yang lebih rendah 94 00:04:14,170 --> 00:04:15,480 bahasa pemrograman. 95 00:04:15,480 --> 00:04:17,880 >> Apa yang membuat tingkat perakitan lebih rendah daripada C? 96 00:04:17,880 --> 00:04:21,660 Nah, dalam perakitan, kami sangat terbatas dalam apa yang bisa kita lakukan. 97 00:04:21,660 --> 00:04:25,120 Tidak ada jika, sementara ini, untuk itu, atau loop apapun. 98 00:04:25,120 --> 00:04:27,560 Tapi Anda bisa mencapai hal yang sama yang mengontrol ini 99 00:04:27,560 --> 00:04:30,270 struktur menawarkan menggunakan operasi terbatas yang 100 00:04:30,270 --> 00:04:32,350 perakitan tidak menyediakan. 101 00:04:32,350 --> 00:04:35,960 Tapi untuk melihat seberapa perakitan tingkat rendah benar-benar, mari kita pergi 102 00:04:35,960 --> 00:04:39,320 satu langkah lebih lanjut dalam penyusunan kami, perakitan. 103 00:04:39,320 --> 00:04:41,890 Adalah tugas assembler untuk mengubah kode assembly 104 00:04:41,890 --> 00:04:44,740 menjadi objek atau kode mesin. 105 00:04:44,740 --> 00:04:47,610 Ingat bahwa assembler tidak perakitan output; 106 00:04:47,610 --> 00:04:51,080 lebih, dibutuhkan dalam perakitan dan kode output mesin. 107 00:04:51,080 --> 00:04:54,040 Kode mesin adalah 1 aktual dan 0 bahwa CPU dapat 108 00:04:54,040 --> 00:04:57,290 mengerti, meskipun kami masih memiliki sedikit pekerjaan yang tersisa 109 00:04:57,290 --> 00:04:59,380 sebelum kita dapat menjalankan program kami. 110 00:04:59,380 --> 00:05:01,400 Mari kita merakit kode perakitan kami dengan melewati 111 00:05:01,400 --> 00:05:04,080 Dentang-c bendera. 112 00:05:04,080 --> 00:05:06,410 Sekarang mari kita lihat apa yang ada di file dirakit. 113 00:05:06,410 --> 00:05:09,220 >> Nah, itu tidak membantu kami sangat banyak. 114 00:05:09,220 --> 00:05:11,340 Ingat bahwa kode mesin adalah satu dan nol yang 115 00:05:11,340 --> 00:05:13,240 komputer Anda dapat mengerti. 116 00:05:13,240 --> 00:05:16,080 Itu tidak berarti itu mudah bagi kita untuk memahami. 117 00:05:16,080 --> 00:05:19,160 Jadi persis bagaimana tingkat rendah adalah perakitan? 118 00:05:19,160 --> 00:05:21,480 Ini hampir sama dengan kode obyek. 119 00:05:21,480 --> 00:05:24,300 Pergi dari perakitan ke kode objek jauh lebih dari sebuah 120 00:05:24,300 --> 00:05:27,540 terjemahan dari transformasi, yang mengapa 121 00:05:27,540 --> 00:05:29,310 seseorang tidak mungkin mempertimbangkan assembler untuk 122 00:05:29,310 --> 00:05:31,400 melakukan kompilasi aktual. 123 00:05:31,400 --> 00:05:34,110 Bahkan, itu cukup mudah untuk menerjemahkan manual dari 124 00:05:34,110 --> 00:05:36,050 perakitan ke kode mesin. 125 00:05:36,050 --> 00:05:39,040 Melihat perakitan untuk fungsi utama, yaitu baris pertama 126 00:05:39,040 --> 00:05:42,100 terjadi sesuai dengan 0x55 heksadesimal. 127 00:05:42,100 --> 00:05:45,470 Dalam biner, itu 1010101. 128 00:05:45,470 --> 00:05:49,300 Baris kedua terjadi sesuai 0x895 heksadesimal. 129 00:05:49,300 --> 00:05:51,290 Dan, selanjutnya 0x56. 130 00:05:51,290 --> 00:05:53,730 Mengingat meja relatif sederhana, Anda bisa menerjemahkan 131 00:05:53,730 --> 00:05:57,130 perakitan ke dalam kode mesin yang dapat mengerti juga. 132 00:05:57,130 --> 00:05:58,810 >> Jadi ada satu langkah yang tersisa dalam 133 00:05:58,810 --> 00:06:01,150 kompilasi, yang menghubungkan. 134 00:06:01,150 --> 00:06:04,530 Menghubungkan menggabungkan sekelompok file objek ke dalam satu file besar 135 00:06:04,530 --> 00:06:06,380 bahwa Anda benar-benar bisa mengeksekusi. 136 00:06:06,380 --> 00:06:08,570 Menghubungkan sangat tergantung dari sistem. 137 00:06:08,570 --> 00:06:11,030 Jadi cara termudah untuk mendapatkan dentang hanya menghubungkan objek 138 00:06:11,030 --> 00:06:13,920 file bersama adalah untuk memanggil dentang pada semua file yang 139 00:06:13,920 --> 00:06:15,190 Anda ingin menghubungkan bersama-sama. 140 00:06:15,190 --> 00:06:18,740 Jika Anda tentukan. File o, maka tidak akan perlu memproses ulang, 141 00:06:18,740 --> 00:06:21,680 kompilasi, dan merakit semua kode sumber Anda. 142 00:06:21,680 --> 00:06:23,960 Mari kita melempar fungsi matematika ke dalam file kami, sehingga kami memiliki 143 00:06:23,960 --> 00:06:25,210 sesuatu untuk menghubungkan masuk 144 00:06:34,220 --> 00:06:37,010 Sekarang mari kita compile kembali ke kode obyek dan 145 00:06:37,010 --> 00:06:38,260 sebut dentang di atasnya. 146 00:06:40,560 --> 00:06:41,420 Ups. 147 00:06:41,420 --> 00:06:43,790 Karena kita termasuk fungsi matematika, kita perlu untuk link dalam 148 00:06:43,790 --> 00:06:46,610 perpustakaan matematika dengan-lm. 149 00:06:46,610 --> 00:06:48,990 >> Jika kita ingin menghubungkan bersama sekelompok. O file yang kita 150 00:06:48,990 --> 00:06:51,420 menulis kita sendiri, kita hanya akan menentukan mereka semua pada 151 00:06:51,420 --> 00:06:52,460 baris perintah. 152 00:06:52,460 --> 00:06:55,320 Pembatasan adalah bahwa satu-satunya dari file-file ini harus 153 00:06:55,320 --> 00:06:57,790 sebenarnya menetapkan fungsi utama, atau yang lain 154 00:06:57,790 --> 00:06:59,930 executable yang dihasilkan tidak akan tahu di mana untuk memulai 155 00:06:59,930 --> 00:07:00,910 menjalankan kode Anda. 156 00:07:00,910 --> 00:07:03,360 Apa perbedaan antara menentukan file untuk link dalam 157 00:07:03,360 --> 00:07:06,600 dengan-l dan hanya menentukan file secara langsung? 158 00:07:06,600 --> 00:07:07,440 Tidak ada. 159 00:07:07,440 --> 00:07:09,850 Hanya saja dentang yang terjadi untuk mengetahui berkas apa 160 00:07:09,850 --> 00:07:12,560 sesuatu seperti-lm terjadi untuk merujuk. 161 00:07:12,560 --> 00:07:14,700 Jika Anda tahu file yang sendiri, Anda bisa menentukan hal itu 162 00:07:14,700 --> 00:07:15,930 eksplisit. 163 00:07:15,930 --> 00:07:18,990 Hanya ingat bahwa semua-l bendera harus datang di akhir 164 00:07:18,990 --> 00:07:20,770 permintaan klien Anda. 165 00:07:20,770 --> 00:07:22,300 >> Dan itu semua ada untuk itu. 166 00:07:22,300 --> 00:07:24,940 Bila Anda hanya menjalankan dentang pada beberapa file, ini adalah apa itu 167 00:07:24,940 --> 00:07:26,350 benar-benar melakukannya. 168 00:07:26,350 --> 00:07:29,490 Nama saya Rob Bowden, dan ini adalah CS50.