プログラムが動作する原理(仕組み)について

当ページのリンクには広告が含まれています。

プログラミング言語をコンピュータはどのように解釈し、実行しているのでしょうか?

Visual Studio でプログラムを実行する時の「ビルド」とは、どういう意味があるのでしょうか?

その辺を疑問に持たれている方も多いと思いますので、今後プログラミングを勉強していく上で知っておきたいプログラムの動作原理(仕組み)について解説します。

プログラムを実行するまでの流れ

プログラミング言語でプログラムを書いて、それを実行するまでには以下の手順が必要になります。

そして、これら一連の処理を行ってくれるツールが Visual Studio です。


それでは、手順を細かく見ていきましょう。

プログラム(ソースコード)をマシン語に翻訳するコンパイル

コンピュータ(CPU)は、マシン語と呼ばれる特殊な言語しか解釈できません。

従って、人がコンピュータに指示を与える場合、このマシン語を使います。

マシン語は0~255の数値を羅列したものなので、人がそのまま使うには適していません。

そこで、人間が理解しやすいプログラミング言語を作り、コンピュータ(CPU)に実行させる時はマシン語に翻訳するという方法が考え出されました。

プログラミング言語で書かれたプログラム(ソースコード)をマシン語に翻訳する行為を「コンパイル」と呼び、翻訳するためのソフトウェアを「コンパイラ」と呼んでいます。

OS上で実行可能な状態に整えるビルド

コンパイラを使うとマシン語に翻訳はしてくれますが、そのままでは実行できる状態ではありません。

通常、実行可能なマシン語のプログラムは、OSの元(管理下)で実行されます。

そのため、OSの管理下で正しく実行するための管理情報や、OS上で実行する際に必要となる共通プログラム(マシン語)、或いはプログラミング言語で書かれたコンパイル済み(マシン語)プログラムと結合する必要があります。

この作業を「ビルド」と呼んでいます。

ビルドされた結果は、拡張子 「.EXE」のファイルに書き出されます。

プログラムの実行

エクセルやワードをはじめとするアプリケーションは、拡張子 EXE という名前でディスクに保存されています。

これを実行(ショートカット又はファイルをダブルクリック)すると、ファイルの中身(マシン語に翻訳されたプログラム)がメモリに読み込まれ、CPUがマシン語を1語づつ解釈しながら、処理を実行していきます。

ここまでが、プログラミング言語を実行する原理(仕組み)になります。

どんなプログラミング言語であっても、必ずマシン語に翻訳してからでないと実行できないという制約があることを念頭に、次は課題について見ていきたいと思います。

コンパイル方式の課題

プログラミング言語で書かれたプログラム(ソースコード)を、一旦マシン語に翻訳してCPUに実行させるという手順を「コンパイル方式」と呼んでいます。

このコンパイル方式は優れた方式ですが、全てのプログラム をマシン語に変換し終わらないと、実行できないという制約が生じます。

もし、大きめのプログラムを作ったとして、その翻訳に5分掛かったとしましょう。

プログラムを実行してから1か所ミスに気づき、それを修正したとしても、実行して動作確認するまでに5分は必ず待たされる事に成ります。

これだと、待ち時間で思考が中断されたり、動作確認テストがなかなか進みませんよね。

結果的に、「プログラムを実行する前にソースコードにミスが無いか十分確認する」という行為が必要となり、気軽に作って試すという事が難しくなります。

実際のプログラムでは、機能ごとにソースコードを分割することが普通なので、変更したソースコードだけをコンパイルすることでコンパイル時間の短縮が図られていましたが、それでも数十秒から規模によって数分は待たされます。

インタープリタ方式の登場

英語を知らない日本人と、日本語を知らないアメリカ人が会話する時、間に通訳を挟みますよね。

この時の会話は、一通りの短い文章を通訳に話して、その分だけ英語に翻訳してもらうという形になります。

通訳には同時通訳というのがあって、こちらが話している内容を瞬時に理解して、英語に翻訳してくれますが、コンピュータの世界では、この方式をインタープリタ方式と呼んでいます。

つまり、プログラミング言語で書かれた1行1行を、リアルタイムにマシン語に翻訳して、CPUに処理させる方式です。

インタープリタ方式の仕組みと課題

インタープリタ方式は、プログラミング言語で書かれたプログラム (ソースコード) を、1行ずつ翻訳して実行してくれます。

これは、1行入力すると、その結果が瞬時に返ってくるという事を意味します。

つまり、入力した命令文(コマンド)の結果を見ながら、プログラミングが出来るということです。

この方式が登場してから、気軽にプログラミングが出来る様になりました。

ただし、厳密に言うとインタープリタは直接マシン語に翻訳してくれるわけではありません。

というのは、直接マシン語に翻訳するという行為は、結構重たい処理だからです。

そこで、バーチャルマシンと呼ばれるソフトウェアを使う案が浮上しました。

バーチャルマシンは、指示された命令を解釈して実行するようなソフトウェアであり、CPUの動作をソフトウェアで模倣した存在です。

バーチャルマシンに対して指示する命令=言語は中間言語と呼ばれており、バーチャルマシンは中間言語に書かれた命令を忠実に実行します。

例えばインタープリタで代表的なPythonを例にすると、1行入力するごとに中間言語に変換され、バーチャルマシンに渡されます。

バーチャルマシンは中間言語に書かれた内容を実行した後、次の中間言語が来るまで待機します。

CPUは四則演算や簡単な条件分岐、ループ処理しか処理出来ません。

例えば「10個の配列変数を作成する」するという行為をCPUに行わせようとした場合、数十個の命令をCPUに与えなければなりません。

一方中間言語は、少しの命令で複雑な処理をバーチャルマシンに指示できるようになっています。

というか、短い命令で多くの事を出来る様にしたものがバーチャルマシンだからです。

従って、マシン語に直接翻訳するより中間言語に翻訳する方が、翻訳時間が短く、リアルタイムに処理が出来るのです。

しかし、メリットばかりではありません。

コンパイル方式では、ソースコードをまとめて変換し、まとめてCPUに指示するため、最初に翻訳処理の時間は掛かっても、いざCPUが実行する際の翻訳時間はゼロです。

しかし、インタープリタ方式では、ソースコードを入力した都度、中間言語に翻訳され、それをバーチャルマシンが解釈して処理するという手順を踏みます。

単純な1命令を実行するのであればともかく、同じ処理をループで何度も繰り返すような場合、この一連の処理は大きなオーバーヘッドとなって、処理速度を低下させてしまいます。

JIT(Just-In Time)方式の登場

インタープリタ方式の課題である処理時間の遅さを解決する方法として、JIT (Just-In Time)が考え出されました。

事前にコンパイルせず、入力の都度中間言語に変換するという考え方はインタープリタと同じですが、入力されたソースコードは可能な限り、その場でマシン語に変換してしまおうというものです。

現在では多くのインタープリタ方式のプログラミング言語が、JIT方式を採用しています。

そして、本サイトで扱うC#に関しても、JIT方式になります。

Microsoft .NET Frameworkとは

さて、Microsoft .NET Frameworkとは何でしょう?

簡単に言うと、バーチャルマシン+共通クラスの集合体(共通に利用できるプログラム群)です。

C#はJIT方式ですから、 一部は中間言語に、一部はマシン語に翻訳されます。

そして、それだけではなく、ファイルやメモリなどOSに依存する機能を扱うクラス、ネットワークを扱うクラス、数値や文字を扱うクラスなど、様々な用途に向けたクラスが大量に用意されていて、中間言語やマシン語から自由に呼び出すことができるようになっています。

このMicrosoft .NET Frameworkは、順次バージョンアップがされていて、Windows10のバージョンアップと共にマイクロソフトからWindowsUpdateにより配布されます。

ただし、 Microsoft .NET Framework の最新バージョンが登場したとしても、すぐにWindowsUpdateで配布されるわけではありません。

また、全てのパソコンがWindowsUpdateを適切に適用している保証はないので、 Microsoft .NET Framework の最新機能を使う際には注意が必要です。

ちなみに、 Microsoft .NET Framework は、マイクロソフトが提供するプログラミング言語(C++、C#、VB.NET、F#)から呼び出しが可能なので、C#からVB.NET、或いはF#からC#など異なる言語で書かれたソースコードの移植もやりやすくなっています。

まとめ

いかがでしたでしょうか。

  • プログラミング言語で作成したプログラム(ソースコード)は、コンパイラーを使ってマシン語に翻訳し、Windows上で実行可能な形式に整える必要がある。
  • しかし、コンパイル方式は最初に翻訳する時間が必要となるため、それを改善するために、ソースコードをリアルタイムに中間言語へ変換・実行してくれるインタープリタ方式が登場した。
  • ただし、インタープリタ方式はループ処理のように、同じ処理を繰り返すようなケースでは、1行実行するごとに翻訳と解釈の時間が掛かるため、結果的に処理速度が遅くなる。
  • それを解決するため、実行時に可能な限りマシン語に翻訳するJIT方式(Just-in Time方式)が登場した。
  • C#の場合もJIT方式を採用しているが、JavaやPythonとは異なり、Microsoft .NET Framework と呼ばれるバーチャルマシン+共通クラスライブラリが提供されている。

ということでしたね。

動作原理をある程度把握すると、プログラミングをする上で理解が早くなると思いますので、是非覚えておいてください。