2023年03月26日くいなちゃん


6さいからのプログラミング」第1話では、コンピュータがプログラムを動かす仕組みと、プログラムの作り方を説明します!

1コンピュータの中身

アプリやOSなどのプログラムがコンピュータ上で一体どのような仕組みで動いているのかを、PCやスマートフォン端末を分解して見てみましょう。
PCを分解すると、主に図1-1のようになっています。
コンピュータの中身
図1-1: コンピュータの中身
「プリント基板きばん(PCではよく「マザーボード」と呼ばれます)という薄い板の上に「CPUシーピーユー」と「メインメモリ」が載っていて、それ以外にもいろいろなものがケーブルで繋がれています。 スマートフォンでも、各部品がより一体化しているという違いはありますが大体似た構成です。
さて、主役はCPUで、計算したり記憶したり他の部品に指示を出す機能を持っており、ちょうど人間の脳のような部品です。 CPUには「レジスタ」と呼ばれる記憶領域がありますが、しかし容量は小さくほんの少しの情報しか憶えておくことができません。 そこでたくさん憶えることのできる部品「メインメモリ」と繋がっています。
メインメモリ」は、CPUとは比較にならないほど多くの情報を憶えることができる部品です。 しかし電源がオフになると全情報を忘れてしまうという欠点や、もっとたくさんの情報を憶えさせたいという要求もあるため、さらに「HDDエイチディーディー(ハードディスクドライブ)や「SSDエスエスディー」といった「補助記憶装置ほじょきおくそうち」が繋げられます。
これらは電気を使って情報をやりとりします。 CPUがCPU内部にあるレジスタの情報を読み書きするのは非常に速いのですが、メインメモリまで読みにいくのは時間がかかり、HDDやSSDになるとさらに遅くなります。 そこで頻繁に使う情報はCPUに近いところに置き滅多に使わない情報は遠くの装置に置くようにします。 そして、CPUとメインメモリの間に、メインメモリよりも速く読み書きできる「キャッシュメモリ」というものを搭載したり、「1キャッシュ」「2キャッシュ」のように何段階ものキャッシュメモリを用意して効率化が図られています(図1-2)。
各種記憶装置
図1-2: 各種記憶装置
これらのほかにも、ディスプレイやスピーカーが繋がったり、「GPUジーピーユー」という、CPUの手助けをする部品が搭載されることもあります。 いずれにせよ基本的にはCPUと、メインメモリなどの各種記憶装置が中枢です。

2プログラムとは

さて、アプリやOSはプログラムで出来ています。 プログラムとは、CPUに対して「ああしろこうしろ」という手順を書いた、料理のレシピのようなものです(図2-1)。
  1. 「ダウンロードを開始します」というメッセージを表示せよ。
  2. 「OK」ボタンが押されるまで待機せよ。
  3. ダウンロードを開始せよ。
図2-1: プログラムのイメージ
CPUはこれらの命令を、1つずつ順番に実行していきます。 ただし実際のプログラムにはもっと膨大な数の命令が書かれており、CPUは1秒間に数億個もの速度で命令を実行していきます。
コンピュータの電源がオフのときにはCPUもメインメモリも情報を忘れてしまいます。 そこでプログラムは普段、CPUやメインメモリではなく、HDDやSSDなどに保存しておきます。 しかしCPUがプログラムの命令を読むたびにHDDやSSDにアクセスしては遅すぎるので、プログラムは起動するタイミングでメインメモリにコピーし、CPUはメインメモリからプログラムの命令を1つずつ取って実行していきます(図2-2)。
プログラム実行の流れ
図2-2: プログラム実行の流れ
アプリもOSも基本的に同じ流れで動きます。 PCやスマートフォンの電源を入れると、WindowsやiOSやAndroidなどのOSのプログラムがメインメモリに読み込まれてCPUにより実行され、アプリを起動するとアプリのプログラムが同様に実行されます。
つまりプログラミングとは、この膨大な命令群を作り上げる作業になります。

3メインメモリの構造

では具体的に、メインメモリ上のプログラムを見ていきましょう。 実際のメインメモリは図3-1のような構造になっています。
メインメモリの構造
図3-1: メインメモリの構造
メインメモリは情報が格納された長い帯のイメージです。 図では「B8 03 00 00 00 83 C0」という情報が入っていますが、この左右にも延々と続いています。
メインメモリの情報は、よく「16進数しんすう」という書き方で表されます。 わたしたちは数値を書くとき「0123456789」の10種類の記号を使いますが、これは「10進数しんすう」と呼ばれ、16進数では「0123456789ABCDEF」の16種類の記号で数値を表します。 ちなみに「01」の2種類だけで数値を表す「2進数しんすう」もプログラミングではよく使われます。 「9」に「1」を足すと、10進数では繰り上がって「10」になりますが、16進数では「A」になります(表3-1)。
表3-1: 10進数と16進数と2進数
10進数 16進数 2進数
0 0 0
1 1 1
2 2 10
3 3 11
4 4 100
5 5 101
6 6 110
7 7 111
8 8 1000
9 9 1001
10 A 1010
11 B 1011
12 C 1100
13 D 1101
14 E 1110
15 F 1111
16 10 10000
16進数では「F」に「1」を足すと繰り上がって「10」になります。
さてもう一度先ほどの図を再掲します(図3-2)。
メインメモリの構造2
図3-2: メインメモリの構造2
さて、この図ではメインメモリの上部にも16進数が書かれていますが、これは「アドレス」と呼ばれ、メインメモリの先頭から順番に1つずつ増やしながら割り当てられています。 アドレスを「○○番地ばんち」と住所のように表現すると、この図でB8が入っているのは「3C番地」、83が入っているのは「41番地」になっています。 また「42番地にはC0が入っている」ともいえます。
メインメモリの1つの番地には、16進数で「00~FF」の範囲の値を入れることができます。 これは10進数では「0~255」、2進数では「00000000~11111111」の値です。 この値1つあたりの長さを「1バイト」と呼び、2進数で表したときの各桁の長さを「1ビット」と呼びます(図3-3)。
バイトとビット
図3-3: バイトとビット
1バイトの情報は2進数で「00000000~11111111」の8桁で表せますので、「1バイト=8ビット」です。 例えば「B8 03 00 00 00 83 C0」という情報は、7バイトであり、また56ビットです。

4機械語

先ほどプログラムは命令の集まりだと言いましたが、CPUは実は日本語や英語ではなく「機械語きかいご」と呼ばれる専用の言語しか理解できないため、プログラムは機械語で作る必要があります。 図4-1は機械語のプログラムの例です。

B8 03 00 00 00 83 C0 02 A3 A0 00 00 00 ...

図4-1: 機械語のプログラム
16進数なので一見難しそうですが、1つ1つの命令は単純です。 この機械語は表4-1のような意味になっています。
表4-1: 機械語のプログラムの意味
機械語 意味
B8 03 00 00 00 CPUのレジスタに3を書き込む。
83 C0 02 CPUのレジスタの値を2増やす。
A3 A0 00 00 00 CPUのレジスタの値をメインメモリのA0番地に書き込む。
このプログラムをよく読むと、CPUが「3+2」を計算したのち、メインメモリのA0番地に5を書き込むプログラムであることが解ります。 以上のような機械語を書いていけば、最終的にはアプリやOSが完成します。

5コンパイル

しかし実際にプログラムを機械語で書いていくのは大変なので、現在では普通もっと便利な方法が行われます。 人間にとって解りやすい言葉で書き、あとで機械語へ自動翻訳させるのです(図5-1)。
コンパイル
図5-1: コンパイル
この自動翻訳することを「コンパイル」といい、専用のアプリを使って行います。 コンパイルしてくれるアプリのことを「コンパイラ」といい、また翻訳前のプログラムのことを「ソースコード」といいます。
コンパイルの仕組みを用いると、非常に簡単にプログラムが作れる上に、他にもたくさんの利点があります。 例えば、CPUの種類によってCPUが読める機械語が異なるのですが、コンパイラの設定を変えるだけで、翻訳前のソースコードを修正することなく別のCPUにも対応できたりします。 また、コンパイルするときに優れた機械語になるように調整する「最適化さいてきか」も行ってくれます。
コンパイラもアプリなので、プログラミングによって作り出すことができます。 いつかコンパイラ作りに挑戦してみると良いでしょう。

6プログラミング言語の種類

さて、翻訳前のソースコードはどのような言葉で書かれるかというと、これもまた日本語や英語ではなく、「プログラミング言語げんご」と呼ばれる専用の言語です。 そしてこのプログラミング言語にもたくさんの種類が存在します。
初めはいくつかのプログラミング言語しか存在しなかったのですが、「こんな言語のほうが便利だろう」「自分ならこう設計をする」と人々がやっているうちに、いつの間にか数百種類になってしまいました。 しかも用途により適材適所で使い分けられています。 表6-1に、いくつかのプログラミング言語を挙げます。
表6-1: プログラミング言語の例
名前 説明
アセンブリ言語げんご 機械語の命令を、人間がぎりぎり読める言葉に1対1で置き換えただけのような言語。 機械語よりはこれで書いたほうが解りやすいです。
Cシー言語げんご 最も多くの人が習得している基本的な言語。 これを勉強するとコンピュータの仕組みにも詳しくなれるため良いです。
C++シープラスプラス C言語を拡張した言語。 大抵C言語をそのまま書くことは少なく、C++が使われることが多いです。 C言語と合わせて「C/C++」と表現されたりします。
Javaジャヴァ 多くの種類のコンピュータで動作可能な言語。 一時期下火になったり、Androidアプリを作る際の標準言語となって息を吹き返したりと、流行り廃りに波があります。
C#シーシャープ Windows界隈で人気の言語。 名前に「C」と付きますが、中身はC/C++よりもJavaに近いです。 Windows用アプリを作るときによく使われます。
JavaScriptジャヴァスクリプト 凝ったWebサイトを作るときに使われる言語。 主にWebブラウザ上で動作します。 名前に「Java」と付きますが、Javaとは全く異なる言語です。
PerlパールPHPピーエイチピーPythonパイソンRubyルビー 凝ったWebサイトを作るときに、JavaScriptとは別にサーバ側で使われる言語。 また、Pythonは機械学習(人工知能に関する分野)などでもよく使われています。
関数型言語かんすうがたげんご C言語などとは異なる発想の言語。 関数型言語には「LISPリスプ」「Haskellハスケル」「F#エフシャープ」などが存在します。
この他にも様々な言語が存在します。 C#が登場するまでは「Visualヴィジュアル Basicベーシック」が優勢だったり、C/C++に代わる言語として「Rustラスト」が登場したり、言語の流行り廃りは著しいです。 ただ、数十年前から最も多くの人が習得していて今なお使われている言語は「C言語」ですので、まずはC言語を中心に学習すると普遍的な知識が習得できて良いかと思います。
また、機械語の命令を人間が読めるぎりぎりの言葉に置き換えただけの「アセンブリ言語」がありますが、CPUに特殊なことをさせたい場合にごくまれに使うことがあり、C言語のプログラムの中に埋め込むこともできます。 ちなみに、アセンブリ言語のプログラムを機械語に翻訳するときはコンパイルではなく「アセンブル」といい、翻訳を行ってくれるアプリを「アセンブラ」と呼びます。
プログラミング言語によっては、機械語にコンパイルしてから実行するのではなく、実行している最中に機械語に逐次翻訳しながら進めるものもあります。 こうすると実行速度は遅くなりますが、ソースコードを修正するたびにコンパイルする手間がかかることを短縮できます。
以上がプログラムを作る手順になります。 基本的には、「ソースコードを書いて、機械語にコンパイルして実行」という流れです。 ソースコードはテキストエディタで作れます。 コンパイルの仕方は、各コンパイラの説明書に書かれています。 あとは、ソースコードの書き方を学べばOSやアプリが作れそうです。

7コンパイラ

最後に、各コンパイラを用意する方法について簡単に説明しておきます。 本講義ではインストール方法などは割愛しますが、詳しい使い方はそれぞれの公式サイトなどを参照してください。
C/C++では、Windowsならば「Visual Studio」というパッケージに含まれる「Visual C++」というアプリがよく使われます。 コンパイラだけでなく、テキストエディタや他の便利な機能も揃っています。 無料版も配布されています。 Visual StudioにはC#も含まれており、C#を書きたい人も通常はこれを使います。 LinuxやBSDでC/C++を書くときは、コンパイラは「Clang」や「GCC」を使うと良いでしょう。
アセンブリ言語をアセンブルする際のアセンブラは、大抵C/C++のコンパイラに付属しているのでそれを使います。
JavaScriptはWebブラウザによって動かされるため、コンパイルは必要なく、コンパイラも不要です。 このサイトを見るのに使っているWebブラウザと、テキストエディタがあれば十分です。
次回からは、C言語やアセンブリ言語やJavaScriptなど、様々な言語のソースコードを見ながら、多くのプログラミング言語で必須となる知識をまとめて解説します!
1679822278jaf