1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROBボーデン:レッツは、コンパイラの話。 2 00:00:09,100 --> 00:00:11,490 この時点までは、あなただけにあなたのソースコードを入力した 3 00:00:11,490 --> 00:00:14,260 いくつかのファイルであり、この大きな黒いボックスを介してそれらを送信 4 00:00:14,260 --> 00:00:16,890 Clangのは、出ない、実行可能ファイルを付属してい 5 00:00:16,890 --> 00:00:19,430 まさにあなたがソースコードに書いている。 6 00:00:19,430 --> 00:00:22,170 てきていると魔法のように、我々は近づいていくつもりです 7 00:00:22,170 --> 00:00:23,590 実際に何が起こっているかを見てみ 8 00:00:23,590 --> 00:00:25,220 我々は、ファイルをコンパイルするとき。 9 00:00:25,220 --> 00:00:28,580 それでは、それは何かをコンパイルするにはどういう意味ですか? 10 00:00:28,580 --> 00:00:31,150 >> まあ、最も一般的な意味では、それだけで意味 11 00:00:31,150 --> 00:00:32,580 1で書かれたコード変換 12 00:00:32,580 --> 00:00:34,680 別のプログラミング言語。 13 00:00:34,680 --> 00:00:37,550 しかし、通常の人々は、彼らが何かをコンパイルすると言うとき、彼らは 14 00:00:37,550 --> 00:00:39,660 彼らはより高いレベルのプログラミングから、それを取っているわけで 15 00:00:39,660 --> 00:00:42,460 低レベルのプログラミング言語への言語。 16 00:00:42,460 --> 00:00:44,960 これらは非常に主観的な用語のように見えるかもしれません。 17 00:00:44,960 --> 00:00:48,090 たとえば、あなたはおそらく高いとしてCはないと思う 18 00:00:48,090 --> 00:00:51,440 レベルのプログラミング言語が、あなたはそれをコンパイルしてください。 19 00:00:51,440 --> 00:00:52,730 しかし、それはすべて相対的です。 20 00:00:52,730 --> 00:00:55,790 我々が見ていくように、アセンブリコードと最終的にはマシン 21 00:00:55,790 --> 00:00:59,270 我々がダウンしてコンパイルされたコードは紛れもなく低いレベルである 22 00:00:59,270 --> 00:01:00,700 Cより 23 00:01:00,700 --> 00:01:03,310 我々は今日のデモでClangのを使用することがありますが、 24 00:01:03,310 --> 00:01:06,360 たくさんのアイデアはここで他のコンパイラに持ち越し。 25 00:01:06,360 --> 00:01:09,160 >> Clangのは、全体の4つの主要なステップがあります。 26 00:01:09,160 --> 00:01:10,200 コンパイル。 27 00:01:10,200 --> 00:01:15,430 これらは、1、プリプロセッサによって行わ前処理です。2、 28 00:01:15,430 --> 00:01:19,530 コンパイラによるコンパイル、3、組み立て 29 00:01:19,530 --> 00:01:22,010 と、4;アセンブラによって行わ 30 00:01:22,010 --> 00:01:24,640 リンクはリンカによって行われます。 31 00:01:24,640 --> 00:01:27,600 これは、混乱を招くことがあり、その全体のサブステップの1 32 00:01:27,600 --> 00:01:30,980 Clangのコンパイラは、コンパイラと呼ばれていますが、 33 00:01:30,980 --> 00:01:32,530 我々はそれに得るでしょう。 34 00:01:32,530 --> 00:01:35,050 私達は私達の例のような単純なHello Worldプログラムを使用することがあります 35 00:01:35,050 --> 00:01:36,270 このビデオを通して。 36 00:01:36,270 --> 00:01:38,380 のは、見てみましょう。 37 00:01:38,380 --> 00:01:40,330 >> 最初のステップでは、前処理である。 38 00:01:40,330 --> 00:01:42,520 プリプロセッサは何をしますか? 39 00:01:42,520 --> 00:01:45,560 あなたが今まで読んだか、書いてきたほとんどすべてのCプログラムでは、 40 00:01:45,560 --> 00:01:48,310 あなたは、ハッシュで始まる行のコードを使用してきました。 41 00:01:48,310 --> 00:01:51,730 私はそれをハッシュと呼ぶことにしますが、あなたもそれポンド呼び出すことができ、数 42 00:01:51,730 --> 00:01:53,280 記号、または鋭い。 43 00:01:53,280 --> 00:01:56,840 このような行はプリプロセッサディレクティブです。 44 00:01:56,840 --> 00:02:00,650 おそらく、#defineや#前に含まれて見られるが、そこにしました 45 00:02:00,650 --> 00:02:03,690 プリプロセッサが認識していることをいくつかのより多くのです。 46 00:02:03,690 --> 00:02:07,340 #私たちのHello Worldの例にdefineを追加してみましょう。 47 00:02:07,340 --> 00:02:11,690 さて、このファイル上だけでプリプロセッサを実行してみましょう。 48 00:02:11,690 --> 00:02:16,150 clage-Eフラグを渡すことで、あなたはそれを実行するよう指示している 49 00:02:16,150 --> 00:02:17,880 ただプリプロセッサ。 50 00:02:17,880 --> 00:02:19,130 何が起こるか見てみましょう。 51 00:02:22,250 --> 00:02:24,020 Clangのはただすべてを出してくれるみたいだな 52 00:02:24,020 --> 00:02:25,200 コマンドラインで。 53 00:02:25,200 --> 00:02:27,800 という名前の新しいファイルに、この出力のすべてを保存するために 54 00:02:27,800 --> 00:02:33,850 hello2.cは、我々のコマンドに> hello2.cを追加します。 55 00:02:33,850 --> 00:02:37,800 今度は、私たちのプリプロセスされたファイルを見てみましょう。 56 00:02:37,800 --> 00:02:40,810 >> おっと、私たちの短い小さなプログラムに何が起こったのか? 57 00:02:40,810 --> 00:02:43,890 我々は、このファイルの末尾にすべての道を行く場合は、我々が表示されます 58 00:02:43,890 --> 00:02:46,070 私たちが実際に書いたコードの一部。 59 00:02:46,070 --> 00:02:49,800 #定義がなくなっていることに注意してくださいと名のすべてのインスタンス 60 00:02:49,800 --> 00:02:51,950 我々はに指定されたかを正確に置き換えられました 61 00:02:51,950 --> 00:02:53,590 #行を定義します。 62 00:02:53,590 --> 00:02:56,530 だから、すべてのこれらのtypedefと関数宣言は何ですか 63 00:02:56,530 --> 00:02:58,140 ファイルの先頭にある? 64 00:02:58,140 --> 00:03:00,820 の#defineプリプロセッサだけではなかったことに注意してください 65 00:03:00,820 --> 00:03:02,390 私たちが指定した指令。 66 00:03:02,390 --> 00:03:05,280 また、#stdio.hをインクルードしています。 67 00:03:05,280 --> 00:03:09,560 だから狂ったすべての行はただstdio.hにコピーされた実際には 68 00:03:09,560 --> 00:03:11,810 そしてこのファイルの先頭に貼り付ける。 69 00:03:11,810 --> 00:03:14,110 ヘッダファイルは関数のように有用である理由です 70 00:03:14,110 --> 00:03:15,160 宣言。 71 00:03:15,160 --> 00:03:17,740 代わりに関数のすべてをコピーして貼り付ける必要がある 72 00:03:17,740 --> 00:03:21,050 あなたは、あなたのファイルの先頭に使用する予定の宣言 73 00:03:21,050 --> 00:03:22,990 プリプロセッサは、ヘッダからそれらをコピーして貼り付けます 74 00:03:22,990 --> 00:03:24,140 あなたのためのファイル。 75 00:03:24,140 --> 00:03:26,480 >> 今、私たちは、前処理を行っていることを、我々は上に移動 76 00:03:26,480 --> 00:03:27,680 コンパイル。 77 00:03:27,680 --> 00:03:30,725 これがあるため、我々はこのステップのコンパイルを呼び出す理由は、 78 00:03:30,725 --> 00:03:34,130 Clangのが実際にCからにコンパイルしないステップ 79 00:03:34,130 --> 00:03:35,370 アセンブリコード。 80 00:03:35,370 --> 00:03:38,280 Clangのアセンブリにファイルをダウンしてコンパイルしていますが、するために、 81 00:03:38,280 --> 00:03:42,030 それ以上、それを渡す-Sフラグを続行 82 00:03:42,030 --> 00:03:43,560 コマンドラインで。 83 00:03:43,560 --> 00:03:44,790 レッツは、アセンブリを見てみましょう 84 00:03:44,790 --> 00:03:47,390 出力されたファイル。 85 00:03:47,390 --> 00:03:49,740 それはかなり異なる言語のように見えます。 86 00:03:49,740 --> 00:03:52,660 アセンブリコードは非常にプロセッサ固有のものです。 87 00:03:52,660 --> 00:03:55,440 CS50アプライアンスが実行されているので、この場合、 88 00:03:55,440 --> 00:04:00,470 仮想x86プロセッサ、これはx86アセンブリコードです。 89 00:04:00,470 --> 00:04:03,450 非常に少数の人々は、これらの日のアセンブリコードに直接書き込む 90 00:04:03,450 --> 00:04:06,490 しかし、あなたが今まで書いて、全てのCプログラムは、ダウン変換される 91 00:04:06,490 --> 00:04:07,940 アセンブリに。 92 00:04:07,940 --> 00:04:11,440 再び、我々はアセンブリにC言語をコンパイルし、このステップを呼び出す 93 00:04:11,440 --> 00:04:14,170 私たちは、より高いレベルから低いレベルにしようとしているので、 94 00:04:14,170 --> 00:04:15,480 プログラミング言語。 95 00:04:15,480 --> 00:04:17,880 >> 何がCよりも低いレベルのアセンブリを作る? 96 00:04:17,880 --> 00:04:21,660 まあ、アセンブリに、我々は非常に我々が何ができるかに制限されています。 97 00:04:21,660 --> 00:04:25,120 だ、のための、または任意の種類のwhileループ、の場合全くありません。 98 00:04:25,120 --> 00:04:27,560 しかし、あなたは同じことを成し遂げることができ、これらの制御 99 00:04:27,560 --> 00:04:30,270 構造体は、その限られた操作を使用して提供 100 00:04:30,270 --> 00:04:32,350 アセンブリが​​提供します。 101 00:04:32,350 --> 00:04:35,960 しかし、低レベルのアセンブリが​​本当にどれだけ見て、行ってみよう 102 00:04:35,960 --> 00:04:39,320 私たちのコンパイルで、さらに一歩、組み立てる。 103 00:04:39,320 --> 00:04:41,890 これは、アセンブリ·コードを変換するためのアセンブラの仕事です 104 00:04:41,890 --> 00:04:44,740 オブジェクトまたは機械語コードに変換します。 105 00:04:44,740 --> 00:04:47,610 アセンブラは出力アセンブリをしないことに注意してください。 106 00:04:47,610 --> 00:04:51,080 むしろ、それはアセンブリと出力マシンコードを取り込む。 107 00:04:51,080 --> 00:04:54,040 マシンコードは、CPUができる実際の1と0です 108 00:04:54,040 --> 00:04:57,290 我々はまだ残って仕事のほんの少しを持っているが、理解 109 00:04:57,290 --> 00:04:59,380 私達は私達のプログラムを実行する前に。 110 00:04:59,380 --> 00:05:01,400 通過することによって私たちのアセンブリコードをアセンブルしてみましょう 111 00:05:01,400 --> 00:05:04,080 Clangの-cフラグ。 112 00:05:04,080 --> 00:05:06,410 今すぐ組み立てファイルに何があるか見てみましょう。 113 00:05:06,410 --> 00:05:09,220 >> まあ、それは非常に私たちを助けていません。 114 00:05:09,220 --> 00:05:11,340 マシンコードは、その物およびゼロであることを忘れないでください 115 00:05:11,340 --> 00:05:13,240 コンピュータが理解することができます。 116 00:05:13,240 --> 00:05:16,080 それは私たちが理解しやすいというわけではありません。 117 00:05:16,080 --> 00:05:19,160 だからアセンブリが​​正確にどのように低レベルですか? 118 00:05:19,160 --> 00:05:21,480 これは、オブジェクトコードとほぼ同じです。 119 00:05:21,480 --> 00:05:24,300 アセンブリからのオブジェクトコードに行くことのはるかです 120 00:05:24,300 --> 00:05:27,540 なぜ変態、より翻訳 121 00:05:27,540 --> 00:05:29,310 一つにアセンブラを考慮していないかもしれません 122 00:05:29,310 --> 00:05:31,400 実際のコンパイルを行います。 123 00:05:31,400 --> 00:05:34,110 実際には、それは手動で翻訳することは非常に簡単です 124 00:05:34,110 --> 00:05:36,050 マシンコードにアセンブリ。 125 00:05:36,050 --> 00:05:39,040 その最初の行は、main関数のアセンブリを見てみる 126 00:05:39,040 --> 00:05:42,100 進0x55に対応することを起こる。 127 00:05:42,100 --> 00:05:45,470 バイナリでは、それは1010101です。 128 00:05:45,470 --> 00:05:49,300 二行目は進0x895に対応して発生します。 129 00:05:49,300 --> 00:05:51,290 そして次回、0x56。 130 00:05:51,290 --> 00:05:53,730 比較的簡単な表があると、あなたは翻訳できる 131 00:05:53,730 --> 00:05:57,130 マシンがあまりにも理解できるコードにアセンブリ。 132 00:05:57,130 --> 00:05:58,810 >> そうで残りの1つのステップがあり 133 00:05:58,810 --> 00:06:01,150 リンクされているコンパイル、。 134 00:06:01,150 --> 00:06:04,530 リンクとは、一つの大きなファイルにオブジェクトファイルの束を組み合わせ 135 00:06:04,530 --> 00:06:06,380 あなたが実際に実行できること。 136 00:06:06,380 --> 00:06:08,570 リンクは非常にシステムに依存します。 137 00:06:08,570 --> 00:06:11,030 単にオブジェクトをリンクするClangのを取得するので、最も簡単な方法 138 00:06:11,030 --> 00:06:13,920 一緒にファイルには、そのファイルのすべてにClangのを呼び出すことです。 139 00:06:13,920 --> 00:06:15,190 あなたは一緒にリンクしたい。 140 00:06:15,190 --> 00:06:18,740 あなたはoファイルを指定した場合、それは再処理する必要はありません、 141 00:06:18,740 --> 00:06:21,680 コンパイルして、ソースコードのすべてを組み立てる。 142 00:06:21,680 --> 00:06:23,960 のは、我々のファイルに数学関数を投げるましょう、私たちは持っている 143 00:06:23,960 --> 00:06:25,210 インチにリンクするために何か 144 00:06:34,220 --> 00:06:37,010 今度は、オブジェクトコードに戻ってそれをダウンしてコンパイルしてみましょうと 145 00:06:37,010 --> 00:06:38,260 その上でClangのを呼び出します。 146 00:06:40,560 --> 00:06:41,420 おっと。 147 00:06:41,420 --> 00:06:43,790 我々は数学関数が含まれていたので、我々はにリンクする必要があります 148 00:06:43,790 --> 00:06:46,610 -lmで数学ライブラリ。 149 00:06:46,610 --> 00:06:48,990 >> 我々は我々。oファイルの束を一緒にリンクしたい場合 150 00:06:48,990 --> 00:06:51,420 自分たちで書いたが、我々だけでそれらすべてを指定したい 151 00:06:51,420 --> 00:06:52,460 コマンドライン。 152 00:06:52,460 --> 00:06:55,320 制限により、これらのファイルの1つだけがしなければならないということです 153 00:06:55,320 --> 00:06:57,790 実際にmain関数を指定するか、または他の 154 00:06:57,790 --> 00:06:59,930 生成された実行可能ファイルは、どこから始めればいいのか分からないでしょう 155 00:06:59,930 --> 00:07:00,910 あなたのコードを実行する。 156 00:07:00,910 --> 00:07:03,360 にリンクするファイルを指定するの違いは何ですか 157 00:07:03,360 --> 00:07:06,600 と-lとだけファイルを直接指定して? 158 00:07:06,600 --> 00:07:07,440 何もない。 159 00:07:07,440 --> 00:07:09,850 それだけではClangのは正確にどのファイルを知ってどうなるの 160 00:07:09,850 --> 00:07:12,560 -lmのようなものを参照するために起こります。 161 00:07:12,560 --> 00:07:14,700 あなたは、そのファイルを自分で知っていた場合は、それを指定することができます 162 00:07:14,700 --> 00:07:15,930 明示。 163 00:07:15,930 --> 00:07:18,990 ただ、すべての-lフラグが終わりに来ていることを覚えておいてください 164 00:07:18,990 --> 00:07:20,770 あなたのクライアントの需要。 165 00:07:20,770 --> 00:07:22,300 >> そして、それはこれだけです。 166 00:07:22,300 --> 00:07:24,940 あなただけのいくつかのファイルにClangのを実行すると、これはそれが何である 167 00:07:24,940 --> 00:07:26,350 実際にやって。 168 00:07:26,350 --> 00:07:29,490 私の名前はロブ·ボーデンであり、これはCS50です。