2010年7月29日木曜日

計算機 初歩の初歩 ~計算機は何故動く? ソフトウェア編~

よくよく考えてみれば、計算機の動く仕組みはハード/ソフト両面から説明が必要でした。
ということで、今回はソフトウェア編です。

まずは前々回の内容から。


ノイマン型アーキテクチャの計算機は以下のようなステップを繰り返し行うことで計算を行う。
  1. プログラムカウンタのさすアドレスから次の命令を読み込む
  2. 命令長さの分だけプログラムカウンタを増やす
  3. 制御装置で命令をデコードする。制御装置は計算機の他の部分に対して命令を出したり、
    繰り返しを行うためにプログラムカウンタの値を替えたり、条件分岐のためにALUの状態によって
    プログラムカウンタの値を替えたりすることができる。
  4. ステップ1へ戻る


という部分がありましたが、この計算手順がソフトウェアの基本になります。

「アドレス」とはメモリ上のアドレス(番地)の事で、メモリ上の何番地の情報を参照する、という形で情報を見たり書いたりします。
機械語(演算装置が直接理解できる命令の事。"0"と"1"で構成される為、人間には非常に読みづらい)ではメモリのアドレスを指定するのですが、アセンブラや高級言語では直接のメモリアドレス指定はまず行いません。
しかし、メモリアドレスを意識しておかないと「何故動くの?」という問いに答えられないので書いてみました。
現実問題としてメモリアドレスを意識してコーディングすべき言語はC言語くらいまでです。
(VC++.netでは意識する必要性はありません。VC++までです)

ステップ2.の「命令長さ」ですが、メモリアドレスが指すアドレスは、命令の格納されているアドレスの一番先頭のアドレスです。
その為、アドレスに格納されている命令の長さの分だけアドレスの位置を移動させないとならないわけです。
このあたりの処理はアセンブラや高級言語で意識する必要はありません。

ステップ3.で構造化言語の要素(順次・反復・分岐)が登場します。
高級言語の場合、このレベルでソースの記述を行います。


さて、当たり前のように出てきた単語を解説しますと・・・
『アセンブラ』(wikipediaより引用)

CPUが直接実行できる言語は機械語のみであるが、機械語は数字(内部的には二進数)の羅列なので人間には理解しにくい。そこで、機械語を直接記述するのではなく、機械語の意味を表す略語でプログラムを記述することで、人間により分かりやすくしたものがアセンブリ言語である。アセンブリ言語の文法はCPUのアーキテクチャに依存するため、高級言語のような移植性はない。
アセンブリ言語を機械語に変換する事をアセンブル (assemble) すると言い、それを行うプログラムの事をアセンブラ (assembler) と言う。なお、アセンブリ言語の意味で「アセンブラ」または「アセンブラ言語」(Assembler Language)と呼ぶ場合も多い[1]
アセンブリ言語の命令は、アセンブラに対する命令(疑似命令)やマクロ命令を除き、機械語と1対1で対応し、プログラマがCPUの動作を把握しながらプログラムを記述する事ができる。そのため、
  • 実行速度やプログラムサイズに制限があるアプリケーションで、高級言語であるコンパイラの最適化能力では達成できない最適化を手作業で行いたい場合
  • CPUの動作をプログラマが完全に制御する必要がある場合
  • メモリ容量や演算実行速度などのリソースに厳しい制約がある用途
などにはアセンブリ言語によるプログラムが行われる。現在でも、例えばOSカーネルデバイスドライバ組み込みシステムの開発といった場面で頻繁に用いられる。


機械語よりも人間に近いのですが、CPUの動作一つ一つについて記述が可能⇒記述が必要となります。
ずいぶんと書きづらいのですが、無駄な動きを一つもさせないというプログラミングが可能となります。
ちなみに、アセンブラは低級言語(低水準言語)と言われています。
レベルが低いのではなく、コンピューターに近い⇒原始的 という意味合いからのネーミングと思われます。

『高級言語(高水準言語)』(やはりwikipediaより引用)

「高級」の由来は、コンパイラなどで直接機械語にするのではなく、一度アセンブリ言語に変換されて、機械語に変換されることがあったため、アセンブリ言語を低級言語、低級言語に変換できる言語を高級言語と区別したことから。インタプリタなどでは低級言語ではなく、中間言語にされて実行されることが多い。
アセンブリ言語と比べ、
  • 人間にとってわかりやすい
  • CPUに依存した処理を書かなくてよい
  • メモリ制御IO制御等CPUレベルの操作を意識しなくてよい
という違いがある。広義の意味は主に三番目の理由からである。

人間寄りのプログラミング言語です。
機械語/アセンブラレベルの複数の命令を、高級言語の1つの命令で済ませることが出来ます。
現在のプログラマ(プログラミングが出来る人)はほとんどすべてが高級言語を扱っています。
たまに筆者のようにアセンブラ経験者(※筆者は大学の演習で使用しました)や、組み込み系一本でアセンブラばりばりな技術者がいますが例外的存在になりつつありますね。


一言でまとめると
『計算機は機械語しかわからないが、翻訳(コンパイル)することで高級言語による命令が実現されている』
のが現状であり、現在の計算機を動かしているソフトウェアとなります。
本当にプログラムを書けるというのは、機械語レベル(せめてアセンブラレベル)を理解して高級言語を使用している状態をいうのではないかなぁと思います。

尚、javaが環境を選ばずに動かせるというのは仮想マシン(VM)があるからなのですが、仮想マシン=計算機と見なすとその理由がわかりやすくなります。
仮想マシンを使うことで、どのような環境でも同じ計算機で計算を行うという状況を作り出している。
その結果、環境を選ばない、という利点が生まれているわけです。
一つ余計なもの(仮想マシン)が追加されている為に動きが遅かったり、サーバやクライアントのスペックを無駄に要求されるのですけどね^^; そんな理由から、筆者はjavaが好きじゃなかったりしますが、それも計算機の仕組みを知ればこそです。


やはり、ちゃんと肉付けして説明すると講義数コマ分の分量のある内容だけに消化不良かもしれないですね。
そこまで書ききる気力がないので今日はこの辺で終了です。

0 件のコメント:

コメントを投稿