1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROB Bowden: Chúng ta hãy nói về trình biên dịch. 2 00:00:09,100 --> 00:00:11,490 Cho đến thời điểm này, bạn đã chỉ cần gõ mã nguồn của bạn vào 3 00:00:11,490 --> 00:00:14,260 một số tập tin, gửi cho họ thông qua hộp đen lớn 4 00:00:14,260 --> 00:00:16,890 Clang, và ra đến tập tin thực thi của bạn mà không 5 00:00:16,890 --> 00:00:19,430 chính xác những gì bạn đã viết trong mã nguồn của bạn. 6 00:00:19,430 --> 00:00:22,170 Huyền diệu như đó là được, chúng ta sẽ mất một gần gũi hơn 7 00:00:22,170 --> 00:00:23,590 nhìn vào những gì thực sự xảy ra 8 00:00:23,590 --> 00:00:25,220 khi chúng tôi biên dịch tập tin. 9 00:00:25,220 --> 00:00:28,580 Vì vậy, nó biên dịch một cái gì đó có ý nghĩa gì? 10 00:00:28,580 --> 00:00:31,150 >> Vâng, theo nghĩa chung nhất, nó chỉ có nghĩa 11 00:00:31,150 --> 00:00:32,580 chuyển đổi mã bằng văn bản trong một 12 00:00:32,580 --> 00:00:34,680 ngôn ngữ lập trình khác. 13 00:00:34,680 --> 00:00:37,550 Nhưng thường là khi người nói rằng họ biên dịch gì đó, họ 14 00:00:37,550 --> 00:00:39,660 có nghĩa là họ đang dùng nó từ một lập trình cấp cao hơn 15 00:00:39,660 --> 00:00:42,460 ngôn ngữ để một ngôn ngữ lập trình cấp thấp hơn. 16 00:00:42,460 --> 00:00:44,960 Đây có vẻ như điều kiện rất chủ quan. 17 00:00:44,960 --> 00:00:48,090 Ví dụ, bạn có thể không nghĩ của C như là một cao 18 00:00:48,090 --> 00:00:51,440 mức độ ngôn ngữ lập trình, nhưng bạn biên dịch nó. 19 00:00:51,440 --> 00:00:52,730 Nhưng đó là tất cả tương đối. 20 00:00:52,730 --> 00:00:55,790 Như chúng ta sẽ thấy, mã lắp ráp và cuối cùng máy 21 00:00:55,790 --> 00:00:59,270 mã mà chúng tôi biên dịch xuống là không thể phủ nhận một mức độ thấp hơn 22 00:00:59,270 --> 00:01:00,700 hơn C. 23 00:01:00,700 --> 00:01:03,310 Mặc dù chúng tôi sẽ được sử dụng Clang trong cuộc biểu tình ngày hôm nay, một 24 00:01:03,310 --> 00:01:06,360 rất nhiều các ý tưởng ở đây thực hiện qua các trình biên dịch khác. 25 00:01:06,360 --> 00:01:09,160 >> Clang, có bốn bước chính trong tổng thể 26 00:01:09,160 --> 00:01:10,200 biên dịch. 27 00:01:10,200 --> 00:01:15,430 Đây là một, tiền xử lý được thực hiện bởi tiền xử lý, hai, 28 00:01:15,430 --> 00:01:19,530 biên soạn được thực hiện bởi trình biên dịch, ba, lắp ráp 29 00:01:19,530 --> 00:01:22,010 thực hiện bằng cách lắp ráp và bốn, 30 00:01:22,010 --> 00:01:24,640 liên kết được thực hiện bởi các mối liên kết. 31 00:01:24,640 --> 00:01:27,600 Nó có thể gây nhầm lẫn rằng một trong substeps của toàn bộ 32 00:01:27,600 --> 00:01:30,980 Trình biên dịch Clang được gọi là trình biên dịch, nhưng 33 00:01:30,980 --> 00:01:32,530 chúng tôi sẽ nhận được điều đó. 34 00:01:32,530 --> 00:01:35,050 Chúng tôi sẽ sử dụng một chương trình Hello World đơn giản như ví dụ của chúng ta 35 00:01:35,050 --> 00:01:36,270 suốt video này. 36 00:01:36,270 --> 00:01:38,380 Hãy có một cái nhìn. 37 00:01:38,380 --> 00:01:40,330 >> Bước đầu tiên là tiền xử lý. 38 00:01:40,330 --> 00:01:42,520 Tiền xử lý làm gì? 39 00:01:42,520 --> 00:01:45,560 Trong khá nhiều mọi chương trình C, bạn đã từng đọc hoặc bằng văn bản, 40 00:01:45,560 --> 00:01:48,310 bạn đã sử dụng dòng mã bắt đầu với một băm. 41 00:01:48,310 --> 00:01:51,730 Tôi sẽ gọi nó băm, nhưng bạn cũng có thể gọi nó là bảng Anh, số 42 00:01:51,730 --> 00:01:53,280 đăng nhập, hoặc sắc nét. 43 00:01:53,280 --> 00:01:56,840 Bất kỳ dòng như vậy là một chỉ thị tiền xử lý. 44 00:01:56,840 --> 00:02:00,650 Bạn đã có thể nhìn thấy # define và # bao gồm trước, nhưng có 45 00:02:00,650 --> 00:02:03,690 một số tiền xử lý công nhận. 46 00:02:03,690 --> 00:02:07,340 Hãy thêm một # xác định ví dụ hello thế giới của chúng tôi. 47 00:02:07,340 --> 00:02:11,690 Bây giờ chúng ta hãy chỉ chạy các tiền xử lý trên tập tin này. 48 00:02:11,690 --> 00:02:16,150 Bởi đi qua clage E-flag, bạn đang hướng dẫn cho nó chạy 49 00:02:16,150 --> 00:02:17,880 chỉ cần các tiền xử lý. 50 00:02:17,880 --> 00:02:19,130 Hãy xem những gì xảy ra. 51 00:02:22,250 --> 00:02:24,020 Nó trông giống như Clang chỉ spits ra tất cả mọi thứ 52 00:02:24,020 --> 00:02:25,200 tại dòng lệnh. 53 00:02:25,200 --> 00:02:27,800 Để tiết kiệm tất cả các đầu ra này vào một tập tin mới gọi là 54 00:02:27,800 --> 00:02:33,850 hello2.c, chúng tôi sẽ nối thêm> hello2.c lệnh của chúng tôi. 55 00:02:33,850 --> 00:02:37,800 Bây giờ chúng ta hãy nhìn vào tập tin preprocessed của chúng tôi. 56 00:02:37,800 --> 00:02:40,810 >> Whoa, chuyện gì đã xảy ra với chương trình nhỏ của chúng tôi ngắn? 57 00:02:40,810 --> 00:02:43,890 Nếu chúng ta đi tất cả các cách để dưới cùng của tập tin này, chúng ta sẽ thấy 58 00:02:43,890 --> 00:02:46,070 một số mã mà chúng tôi thực sự đã viết. 59 00:02:46,070 --> 00:02:49,800 Chú ý rằng các định nghĩa # đã biến mất và tất cả các trường hợp của tên 60 00:02:49,800 --> 00:02:51,950 đã được thay thế với chính xác những gì chúng tôi quy định 61 00:02:51,950 --> 00:02:53,590 # xác định dòng. 62 00:02:53,590 --> 00:02:56,530 Vì vậy, tất cả các typedefs và tờ khai chức năng là gì 63 00:02:56,530 --> 00:02:58,140 ở phía trên cùng của tập tin? 64 00:02:58,140 --> 00:03:00,820 Chú ý rằng các định nghĩa # không phải là tiền xử lý chỉ 65 00:03:00,820 --> 00:03:02,390 chỉ thị mà chúng tôi quy định. 66 00:03:02,390 --> 00:03:05,280 Chúng tôi cũng đã # bao gồm stdio.h. 67 00:03:05,280 --> 00:03:09,560 Vì vậy, tất cả các dòng điên thực sự chỉ là stdio.h sao chép 68 00:03:09,560 --> 00:03:11,810 và dán vào đầu của tập tin này. 69 00:03:11,810 --> 00:03:14,110 Đó là lý do tại sao các tập tin tiêu đề rất hữu ích cho các chức năng 70 00:03:14,110 --> 00:03:15,160 tờ khai. 71 00:03:15,160 --> 00:03:17,740 Thay vì cần sao chép và dán tất cả các chức năng 72 00:03:17,740 --> 00:03:21,050 khai báo bạn có kế hoạch sử dụng ở phía trên cùng của tập tin của bạn, 73 00:03:21,050 --> 00:03:22,990 tiền xử lý sẽ sao chép và dán chúng từ tiêu đề 74 00:03:22,990 --> 00:03:24,140 nộp cho bạn. 75 00:03:24,140 --> 00:03:26,480 >> Bây giờ mà chúng tôi đang thực hiện tiền xử lý, chúng tôi di chuyển lên 76 00:03:26,480 --> 00:03:27,680 biên dịch. 77 00:03:27,680 --> 00:03:30,725 Lý do chúng ta gọi là quá trình biên dịch bước là bởi vì đây là 78 00:03:30,725 --> 00:03:34,130 bước Clang thực sự không biên dịch từ C đến 79 00:03:34,130 --> 00:03:35,370 lắp ráp mã. 80 00:03:35,370 --> 00:03:38,280 Để có Clang biên dịch một tập tin để lắp ráp, nhưng 81 00:03:38,280 --> 00:03:42,030 tiếp tục xa hơn, vượt qua nó S-flag 82 00:03:42,030 --> 00:03:43,560 tại dòng lệnh. 83 00:03:43,560 --> 00:03:44,790 Chúng ta hãy nhìn vào lắp ráp 84 00:03:44,790 --> 00:03:47,390 tập tin đã được đưa ra cả. 85 00:03:47,390 --> 00:03:49,740 Nó trông giống như một ngôn ngữ hoàn toàn khác nhau. 86 00:03:49,740 --> 00:03:52,660 Hội đang rất xử lý cụ thể. 87 00:03:52,660 --> 00:03:55,440 Trong trường hợp này, kể từ khi thiết bị CS50 đang chạy trên một 88 00:03:55,440 --> 00:04:00,470 bộ xử lý x86 ảo, đây là mã x86, lắp ráp. 89 00:04:00,470 --> 00:04:03,450 Rất ít người viết trực tiếp trong mã lắp ráp những ngày này, 90 00:04:03,450 --> 00:04:06,490 nhưng tất cả các chương trình C bao giờ bạn viết được chuyển xuống 91 00:04:06,490 --> 00:04:07,940 vào lắp ráp. 92 00:04:07,940 --> 00:04:11,440 Một lần nữa, chúng tôi gọi đây là bước biên dịch C vào lắp ráp 93 00:04:11,440 --> 00:04:14,170 kể từ khi chúng tôi đang đi từ một mức độ cao hơn một mức độ thấp hơn 94 00:04:14,170 --> 00:04:15,480 ngôn ngữ lập trình. 95 00:04:15,480 --> 00:04:17,880 >> Điều gì làm cho mức độ lắp ráp thấp hơn so với C? 96 00:04:17,880 --> 00:04:21,660 Tốt, trong lắp ráp, chúng tôi rất hạn chế trong những gì chúng ta có thể làm. 97 00:04:21,660 --> 00:04:25,120 Có không nếu, trong khi là, cho là, hoặc vòng của bất cứ loại nào. 98 00:04:25,120 --> 00:04:27,560 Nhưng bạn có thể thực hiện những điều tương tự này kiểm soát 99 00:04:27,560 --> 00:04:30,270 cấu trúc cung cấp bằng cách sử dụng các hoạt động hạn chế 100 00:04:30,270 --> 00:04:32,350 lắp ráp không cung cấp. 101 00:04:32,350 --> 00:04:35,960 Tuy nhiên, để xem mức thấp lắp ráp thực sự là như thế nào, chúng ta đi 102 00:04:35,960 --> 00:04:39,320 thêm một bước nữa trong việc biên soạn của chúng tôi, lắp ráp. 103 00:04:39,320 --> 00:04:41,890 Đó là công việc của nhà lắp ráp để chuyển đổi mã lắp ráp 104 00:04:41,890 --> 00:04:44,740 vào đối tượng hoặc mã máy. 105 00:04:44,740 --> 00:04:47,610 Hãy nhớ rằng lắp ráp không lắp ráp đầu ra; 106 00:04:47,610 --> 00:04:51,080 đúng hơn, nó có trong máy lắp ráp và mã kết quả đầu ra. 107 00:04:51,080 --> 00:04:54,040 Mã máy là thực tế của số 1 và 0 mà CPU có thể 108 00:04:54,040 --> 00:04:57,290 hiểu, mặc dù chúng tôi vẫn còn có một chút nhỏ bé của công việc còn lại 109 00:04:57,290 --> 00:04:59,380 trước khi chúng tôi có thể chạy chương trình của chúng tôi. 110 00:04:59,380 --> 00:05:01,400 Hãy lắp ráp mã lắp ráp của chúng tôi bằng cách đi qua 111 00:05:01,400 --> 00:05:04,080 Clang c-flag. 112 00:05:04,080 --> 00:05:06,410 Bây giờ chúng ta hãy xem những gì trong file lắp ráp. 113 00:05:06,410 --> 00:05:09,220 >> Vâng, đó không giúp chúng tôi rất nhiều. 114 00:05:09,220 --> 00:05:11,340 Hãy nhớ rằng mã máy là những người thân và số không 115 00:05:11,340 --> 00:05:13,240 máy tính của bạn có thể hiểu được. 116 00:05:13,240 --> 00:05:16,080 Điều đó không có nghĩa là nó dễ dàng để chúng tôi hiểu. 117 00:05:16,080 --> 00:05:19,160 Vì vậy, chính xác mức độ thấp là lắp ráp? 118 00:05:19,160 --> 00:05:21,480 Nó gần giống với mã đối tượng. 119 00:05:21,480 --> 00:05:24,300 Đi từ lắp ráp để mã đối tượng là nhiều hơn nữa của một 120 00:05:24,300 --> 00:05:27,540 dịch hơn một chuyển đổi, đó là lý do tại sao 121 00:05:27,540 --> 00:05:29,310 không ai có thể xem xét việc lắp ráp để 122 00:05:29,310 --> 00:05:31,400 làm bất cứ biên dịch thực tế. 123 00:05:31,400 --> 00:05:34,110 Trong thực tế, nó rất dễ dàng để tự dịch từ 124 00:05:34,110 --> 00:05:36,050 lắp ráp để mã máy. 125 00:05:36,050 --> 00:05:39,040 Nhìn vào lắp ráp cho một chức năng chính, dòng đầu tiên đó 126 00:05:39,040 --> 00:05:42,100 xảy ra tương ứng với 0x55 thập lục phân. 127 00:05:42,100 --> 00:05:45,470 Trong hệ nhị phân, đó là 1.010.101. 128 00:05:45,470 --> 00:05:49,300 Dòng thứ hai sẽ xảy ra tương ứng 0x895 hệ thập lục phân. 129 00:05:49,300 --> 00:05:51,290 Và, bên cạnh 0x56. 130 00:05:51,290 --> 00:05:53,730 Với một bảng tương đối đơn giản, bạn có thể dịch 131 00:05:53,730 --> 00:05:57,130 lắp ráp thành mã mà máy tính có thể hiểu quá. 132 00:05:57,130 --> 00:05:58,810 >> Vì vậy, có một bước còn lại trong 133 00:05:58,810 --> 00:06:01,150 biên soạn, được liên kết. 134 00:06:01,150 --> 00:06:04,530 Liên kết kết hợp một loạt các đối tượng tập tin thành một tập tin lớn 135 00:06:04,530 --> 00:06:06,380 mà bạn thực sự có thể thực hiện. 136 00:06:06,380 --> 00:06:08,570 Liên kết là rất hệ thống phụ thuộc. 137 00:06:08,570 --> 00:06:11,030 Vì vậy, cách dễ nhất để có được Clang phải chỉ liên kết đối tượng 138 00:06:11,030 --> 00:06:13,920 tập tin với nhau là để gọi Clang trên tất cả các tập tin mà 139 00:06:13,920 --> 00:06:15,190 bạn muốn liên kết lại với nhau. 140 00:06:15,190 --> 00:06:18,740 Nếu bạn chỉ định các tập tin o, sau đó nó sẽ không cần để tái xử lý, 141 00:06:18,740 --> 00:06:21,680 biên dịch, và lắp ráp tất cả các mã nguồn của bạn. 142 00:06:21,680 --> 00:06:23,960 Hãy ném một chức năng toán học vào tập tin của chúng tôi, để chúng tôi có 143 00:06:23,960 --> 00:06:25,210 một cái gì đó để liên kết. 144 00:06:34,220 --> 00:06:37,010 Bây giờ chúng ta hãy biên dịch lại mã đối tượng và 145 00:06:37,010 --> 00:06:38,260 gọi Clang vào nó. 146 00:06:40,560 --> 00:06:41,420 Rất tiếc. 147 00:06:41,420 --> 00:06:43,790 Từ khi chúng tôi bao gồm một chức năng toán học, chúng ta cần phải liên kết 148 00:06:43,790 --> 00:06:46,610 thư viện toán học-lm. 149 00:06:46,610 --> 00:06:48,990 >> Nếu chúng ta muốn liên kết với nhau loạt các o các tập tin mà chúng tôi 150 00:06:48,990 --> 00:06:51,420 đã viết trên của chúng ta, chúng tôi chỉ muốn chỉ định tất cả. 151 00:06:51,420 --> 00:06:52,460 dòng lệnh. 152 00:06:52,460 --> 00:06:55,320 Hạn chế là chỉ có một trong những tập tin này phải 153 00:06:55,320 --> 00:06:57,790 thực sự chỉ định một chức năng chính, hoặc người nào khác 154 00:06:57,790 --> 00:06:59,930 kết quả thực thi sẽ không biết bắt đầu từ đâu 155 00:06:59,930 --> 00:07:00,910 chạy mã của bạn. 156 00:07:00,910 --> 00:07:03,360 Sự khác biệt giữa chỉ định một tập tin để liên kết trong là gì 157 00:07:03,360 --> 00:07:06,600 -l và chỉ cần xác định một tập tin trực tiếp? 158 00:07:06,600 --> 00:07:07,440 Không có gì. 159 00:07:07,440 --> 00:07:09,850 Nó chỉ là Clang xảy ra cho biết tập tin chính xác những gì 160 00:07:09,850 --> 00:07:12,560 một cái gì đó như thế-lm xảy ra để tham khảo. 161 00:07:12,560 --> 00:07:14,700 Nếu bạn biết rằng tập tin chính mình, bạn có thể xác định nó 162 00:07:14,700 --> 00:07:15,930 rõ ràng. 163 00:07:15,930 --> 00:07:18,990 Chỉ cần nhớ rằng tất cả các-l cờ phải đến lúc kết thúc 164 00:07:18,990 --> 00:07:20,770 nhu cầu khách hàng của bạn. 165 00:07:20,770 --> 00:07:22,300 >> Và đó là tất cả để có nó. 166 00:07:22,300 --> 00:07:24,940 Khi bạn chỉ cần chạy Clang trên một số tập tin, đây là những gì nó 167 00:07:24,940 --> 00:07:26,350 thực sự làm. 168 00:07:26,350 --> 00:07:29,490 Tên tôi là Rob Bowden, và đây là CS50.