高等学校情報/情報の科学/CPUの処理の仕組み
加算器が必要[編集]
まず、計算機が必要である。
これは、半加算器や全加算器で作れる。
『高等学校情報/情報の科学/論理回路と半導体』で、半加算器の仕組みを説明した。(※ なお、リンク先の単元で、普通科範囲外の、ダイオードによるAND回路やOR回路の話題も記述しておいた。)
記憶回路が必要[編集]
フリップフロップ[編集]
(※ 普通科の範囲外。)
次に、制御のために、データを保存するのに必要なものを考えよう。パソコンでは、メモリ基板だけでなくCPUにも、データ保存のための領域がある。(メモリ基板やハードディスク) なので、まず、データを記憶できる回路をつくろう。



CPUのための記憶の回路をつくるには、フリップフロップ(flip flop)という論理回路を使う。(普通科目「情報」の範囲外。工業高校科目「ハードウェア」などで習う。)なお、フリップフロップのことを別名で「RSラッチ」または「SRラッチ」ともいう。後述のように、セット(S)とリセット(R)があるからである。なお英語でラッチとは、扉(とびら)などの 掛け金(かけがね)のことである。
フリップフロップでは、Qが出力である。Sは「セット」という入力である。Rは「リセット」という端子である。
まず、OR記号の後ろ(図では右側)についている丸「○」は、NOT回路の略記号である。
SとRが両方とも1の場合は、フリップフロップでは禁止されている。
入力の片方をセットといい、Sであらわす。 入力のもう片方をリセットといい、Rであらわす。
フリップフロップでは、上述の動作原理の図のように、いったん入力してしまえば、その出力がまた入力に戻ってくる仕組みなので、ひきつづき同じ出力になる。
つまり、Qの値にかかわらず、R=0の場合、Qの値は保存される。よって、フリップフロップは1ビットのデータを記憶できる。
S=R=1は不定になるので使用禁止とする。
フリップフロップの真理値表は、次のようになる。
入力 | 出力 | |
---|---|---|
S | R | Q |
0 | 0 | 保持 |
0 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | 禁止 |
なお、フリップフロップによる保存には、電力は消費される。なぜなら、NOT回路のもともとのトランジスタ回路や、AND回路のもともとのダイオード回路には、電源が必要だからである。
フリップフロップの種類は、RSフリップフロップの他にもJKフリップフロップやDフリップフロップなど、たくあんあるが、説明を省略する。



なお、フリップフロップのほかの用途として、下記のようう用途もある。
まず、スイッチなどを入れてオンにする際に、電子回路では、可動部の微細な振動によりオン・オフが何回も変動することによって電圧が変動するチャタリングという現象がある[1]。
フリップフロップの他の用途としては、上述の記録保持のほかにも、フリップフロップを使うと、このチャタリングの除去が出来る。スイッチ回路などの出力側にフリップフロップ的な回路を追加すればいい。、リップフロップの仕組み上、最初にオンになったら、そのまま出力がオンになり続けるので、チャタリングでオフに戻るのを防ぐことが出来るという仕組みである。


なお、クロック信号入力をつけたRSフリップフロップの回路図は、右図のようになる。
レジスタ[編集]
さて、CPUで制御用にデータを保存するためのデバイスのことを、パソコン用語でレジスタ(register)という。
なお、メモリ基板にあるデータ保存のための部分は、レジスタとは呼ばない。
さて、フリップフロップを数個並べれば、これにより、その個数ぶんのビットを記憶できる。
つまり、レジスタをつくるには、フリップフロップを必要な個数、並べれば良い。
市販のCPUのビット数について「64ビット」や「32ビット」、「8ビット」などと紹介されるのは、なんのビット数かというと、一般にCPU内のレジスタのビット数である。
つまり、我々は、レジスタの作り方の原理を理解した事になる。
なおパソコンの場合、プログラミングをする際、どのようなデータをCPUのレジスタに保存するかという事は、コンパイラなど言語処理系が自動的に判断する(※詳しくは後述)。プログラマーは判断しない(C言語では キーワード register を変数宣言に用いることでコンパイラに変数をレジスタに割り付けてほしい旨を表現できるなど、完全に判断していないわけではない)。(※ パソコン以外のマイコンとかは高校の範囲外なので説明しない。)
なお、「レジスタ」の用語は、パソコンCPUに限らず、(組み込み機器などの)マイコンCPUでも ほぼ同様の意味である。
命令レジスタと機械語[編集]
なお、パソコンで「次にどんな命令を実行するか?」(「たとえば次に○○の保存を実行する。その次に、△△のコピー作業を実行する。その次に、××を移動する。」という命令など)という作業も、記憶が必要である。
例えば、命令の種類に番号をつけて、
- かりに、データの移動命令を「1」として、
- かりに、データの保存命令を「2」として、
- かりに、データのコピー命令を「3」とすれば、
- かりに、処理の終了を「99」とすれば、
「たとえば次に○○の保存を実行する。その次に、△△のコピー作業を実行する。その次に、××を移動する。」という命令は、
- まず、「命令2を実行しろ。」「次に命令3を実行しろ。」「その次に命令1を実行しろ。」という命令に置き換えられる。
このように、読込んだ命令を保持するためのレジスタのことを命令レジスタ(instruction register)という。命令レジスタには、「これからCPUが実行する命令1つ」が保存される。
なお、「命令2 → 命令3 → 命令1」という順番で命令を実行するためには、命令レジスタとは別途、メモリ基板などの主記憶装置に「命令2」「命令3」「命令1」などの順番を記憶する必要がある。
このような目的の、メモリへの命令の記憶には、たとえば、(メモリ基板などの)主記憶装置のアドレス200番に命令「2」を保存、アドレス201番に命令「3」を保存、アドレス202番に命令「1」を保存、アドレス203番に命令「99」・・・というふうにする。
アドレス番地 | 命令の種類 |
---|---|
200 | 2 |
201 | 3 |
202 | 1 |
203 | 99 |
などのように、アドレス200〜203番に、それぞれの命令の値を保存するわけである。
そして、処理1「まず、アドレス200番の命令をCPUに読み込んで、命令どおり実行しろ」という処理を行い,それから処理2「命令を実行し終わったら、次のアドレス(つまり前のアドレスに+1した番号のアドレス)を実行しろ」という処理2を繰り返せばいいだけである。
そうすれば、アドレス200番の命令から順に、次のアドレス201の命令、その次のアドレス202の命令、その次のアドレス203の命令、を実行することになる。(「200番」というのは単に説明のために仮に決めた数字である。)そして、アドレス203には終了命令が入っているから、そこで処理が終わる。
このような200から順に201,202,・・・と処理の移動する動作をするためには、「現在、CPUは第何番のアドレスを実行しようとしているか?」という情報を保存するレジスタも必要であり、このような(現在実行中しようとしているアドレスを保存するための)レジスタのことをプログラムカウンタ(program counter)という。なお、上述の説明のように、プログラムカウンタは、命令を実行するたびに、+1されて、次の命令を指すようになる。
このように、命令を実行するには、命令レジスタのほかに、プログラムカウンタと主記憶装置(メモリ)などが必要である。
また、命令レジスタを実行するためには、先ほどの例で、命令を保存したアドレス200〜203番のように、命令を保存したアドレスが必要である。このようなアドレスを命令アドレスという。
さて、CPUが命令を処理しやすいように、命令を「1」や「2」といった数字に置き換えたものが機械語(machine language)である。(※ 上記の命令「1」や命令「2」は、説明用に、この教科書で勝手に決めた番号であるので、専門用語ではないので、暗記しなくてよい。)(※ そもそも機械語はCPUの種類によって異なるので、暗記しなくてよい。)
なお、先ほどは「データの移動命令を「1」として」などと簡単に言ったが、実際には、「どこにあるデータを、どこに移動するか?」という情報が必要である。そのため、「どこのデータを扱うか?」という処理が必要である。
この、「どこのデータを扱うか?」というデータも、レジスタに記憶しとけばいい。
この「どこのデータを扱うか」というデータのことを、アドレス(address)という。
いっぽう、「移動する」「命令する」「コピーする」などのような、アドレスのない、単なる命令の種類のことを、「命令コード」または「命令部」(operation)という。
つまり、命令レジスタでは、命令部とアドレスの2つを記憶する必要がある。
なお、「このパソコンのメモリ基板にあるデータを扱え」というデータも、アドレスの情報である。
で、レジスタは要するに、フリップフロップである。
で、もし読者のあなたが、レジスタさえ理解すれば、命令レジスタもいろいろと分かる事になるから、CPUの命令処理の仕組みも、なんとなく分かるだろう。
説明の都合上、「移動命令」「保存命令」「コピー命令」などと言ったが、実際には、これらの命令は、さらに細かい「読み込み命令」や「書き込み命令」などの組み合わせである。
たとえば、データの「コピー命令」とは、「まずコピー元(メモリ上などにコピー元のデータがある)のデータを読み込み、そして読み込まれたデータをコピー先に書き込む」という命令である。(読み込みをしても、読み込み元のデータは消えない。しかし、書き込み先のデータは上書きされる。)
「保存命令」も、「○○に書き込んでおいたデータを読み込み、それを保存先に書き込む」という命令である。(書き込みをしても、書き込み元のデータは消えない。しかし、書き込み先のデータは上書きされる。)
このように、いくつかの命令は、「読み込み」と「書き込み」という2種類の命令に帰結する。
より正確には、機械語とは、読み込み命令や書き込み命令などの、より根本的な命令に対応するビット列の数値のことを機械語という。
なお上記の説明では、説明の都合上パソコンで説明したが、組み込み機器などのマイコンCPUでも、内部的には機械語で処理している。
条件分岐とプログラムカウンタ[編集]

(※ 高校の範囲外。普通科だけでなく、たぶん工業高校でも習わないかも?)
中学の技術家庭科の技術分野などで、右図のような条件分岐のフローチャートを見たこともあるだろう。
さて、条件分岐の実現方法の仕組みは、さきほど説明したプログラムカウンタを使うだけである。
「条件が満たされた場合のみに、プログラムカウンタに記憶されたアドレス値を、分岐先の命令のアドレスに書き換える」という仕組みを作ればい良いだけである。
アセンブリ言語とプログラミング言語[編集]
アセンブリ言語[編集]
- ※ アセンブリ言語は現在では普通科「情報」の範囲外だが、昔は教えてたらしい。今の普通科高校の教科書でも、「アセンブリ」の用語こそ教科書中には無いものの、図表などで教科書中にアセンブリ言語に似たような概念を示している。
コンピュータは数値しか記憶できないので、
たとえば、コンピュータ設計者が 「
- かりに、データの移動命令を「1」として、
- かりに、データの保存命令を「2」として、
- かりに、データのコピー命令を「3」とすれば、
」
・・と決めるわけだが、しかし、設計者以外の一般の人間には「1」とか「2」だけの数字を見ても意味が分かりづらい。
なお、説明のため「コピー命令を「3」」とか書いたが、実際のパソコンでは、命令は何らかのビット列である。たとえば、「10101011000110」とかビットの数字が並んでいても、人間には意味が分からない。
ビット列になると、一般人には、もっと意味が分からない。
そこで、一般の人間が命令を理解しやすいように、
「
- かりに、データの移動命令を「MOVE」として、
- かりに、データの保存命令を「SAVE」として、
- かりに、データのコピー命令を「COPY」とすれば、
- かりに、処理の終了命令を「STOP」とする。
」
などにしてみよう。(※ この「MOVE」「SAVE」などの命令語は、説明用に仮に決めただけであり、情報科学の専門用語でないので暗記しなくてよい。)
そして、コンピュータ的な
アドレス番地 | 命令の種類 |
---|---|
200 | 2 |
201 | 3 |
202 | 1 |
203 | 99 |
のかわりに、
アドレス番地 | 命令の種類 |
---|---|
200 | SAVE |
201 | COPY |
202 | MOVE |
203 | STOP |
のような文章にすれば、人間にとっても「たとえば次に○○の保存を実行する。その次に、△△のコピー作業を実行する。その次に、××を移動する。」という命令だと理解しやすい。
コンピュータにとっても、命令「MOVE」を「1」に置き換え、同様に命令「SAVE」を「2」に置き換え、命令「COPY」を「3」に置き換え、命令「STOP」を「99」に置き換えれば、処理できる。
この「MOVE」「SAVE」「COPY」「STOP」のように、人間が命令を理解しやすいように、機械語を英単語などに書き換えたもののことを「アセンブリ言語」(assembly lamguage)という。(※ アセンブリ言語は普通科「情報」の範囲外。なお、「MOVE」「SAVE」などは説明用に、仮に、この教科書で決めただけの単語であり、けっして、アセンブリ言語の専門用語ではないので、「MOVE」「SAVE」などは暗記しなくてよい。)(※ そもそもアセンブリ言語はCPUの種類によって異なるので、暗記しなくてよい。)
別途、アセンブリ言語の命令「MOVE」を機械語「1」に置き換え、同様に(アセンブリ言語の)命令「SAVE」を(機械語)「2」に置き換え、同様に命令「COPY」を命令「3」に置き換える、という回路を用意しておけば、その回路を使ってアセンブリ言語を機械語に置き換えできる。
同様に、別途、機械語の命令「1」をアセンブリ言語の命令「MOVE」に置き換え、同様に(機械語の)命令「2」を(アセンブリ言語の)命令「SAVE」に置き換え、同様に命令「3」を命令「COPY」に置き換える、という回路を用意しておけば、その回路を使って機械語をアセンブリ言語に置き換えできる。
(※ 範囲外: )なお、アセンブリ言語は、パソコンでもハードウェアを制御する際に使われる。また、マイコンCPUを制御する際にはアセンブリ言語によるプログラミングが一般に使われる。
プログラミング言語[編集]
- ※ この節は主にパソコンの話題。マイコンの話題は無し。
実際には、アセンブリ言語は、人間が大量のコードを読むには向いていない等の理由があるので、なので、アセンブリ言語をさらに人間が読みやすいように置き換えたプログラミング言語というものが用いられる。
中学で「BASIC」や「C言語」などというプログラミング言語の存在を習ったと思う。
BASICやC言語も、そのプログラムを実行する場合、最終的にはコンピューター内部では、そのプログラミング言語のコードを、機械語の命令に置き換えて、そしてCPUなどが機械語の命令を処理している。
なお、プログラム言語で書かれたコードを、機械語の命令に置き換える装置やソフトウェアのことをコンパイラ(compiler)という。 そして、コンパイラを実行すること(つまり、プログラム言語で書かれたコードを機械語の命令に置き換えること)を「コンパイルする」(compile)などという。
プログラム言語のコードが書かれたファイルのことをソースコードという。あるソフトウェアのソースコードを読めば、もしも読み手に、プログラミング言語の専門知識が充分にあれば、そのソフトウェアのしくみが読み手に分かってしまう。
- (※ 参考。範囲外 :) コンパイルして機械語の命令に置き換えたファイルだけでは、もとのプログラムのコードは読めない。機械語に置き換えたファイルを無理やり読もうとしてファイルを読み取りモードで開いても(システムを破壊する可能性があり危険なので、ためしてはいけない。)、「1f 42 6d 3e 25」みたいな意味不明の文字列があらわれたり、あるいは「z8あgqf 8jゆmfpaw9a:」みたいな意味不明な文字列が現れたりするだけである。
このため、そのソフトウェアのプログラムの仕組みを秘密にしておきたい場合、ソースコードは非公開にして配布せずにしておき、コンパイル後のソフトウェアのみを配布することで、プログラムのしくみを秘密にできる。
- (※ 参考。範囲外 :) なお、ソースコードの書かれたファイルのアイコンを、パソコン上でダブルクリックしても(一般的にアイコンをダブルクリックすると、そのファイルを開くことになる)、単にコードが画面に表示されるだけである。ソースコードの書かれたファイルのアイコンをダブルクリックしても、そのプログラムはまだ機械語でないので、書かれたコードの内容は実行されない。
なお、アセンブリ言語の話に戻るが、「読み込み」命令は、仮に「上書きコピー命令」という命令を根本的な命令と考えれば(※ 「上書きコピー命令」という命令名称は仮名なので覚えなくて良い)、つまり「読み込み」命令とは「CPU外部の(メモリ上などの)読み込み元アドレスにあるデータをもちいて、レジスタのデータを上書きコピーしろ」という命令である。(読み込み元アドレスにある読み込み元データと、上書きをされた(レジスタにある)書き込み先データは、同一内容のデータになるので、コピー命令の一種である。なので「上書きコピー命令」と名付けたわけだ。)
そして、「書き込み」命令も、仮に「上書き」命令というのを考えれば、「書き込み」命令とは「今のレジスタのデータを用いて、CPU外部の(メモリ上やハードディスク上などの)書き込み先アドレスにあるデータを上書きしろ」という命令である。(レジスタにある読み込み元データと、上書きをされた(レジスタにある)書き込み先データは、同一内容のデータになるので、コピー命令の一種である。)
このように、「読み込み」命令も「書き込み」命令も、どちらとも「上書きコピー命令」命令である。単に、レジスタからCPU外部に上書きするか、それともCPU外部からレジスタに上書きするか、・・・という方向性が違うだけである。
このため、アセンブリ言語では「読み込み」や「書き込み」「データの移動」「データの複製コピー」、・・・などの命令を、同一のアセンブリ命令(たとえば命令「MOV」(MOVEが由来だが、作業内容は「移動」ではなく「上書きコピー」である) )で扱っている場合も多い。
なお、「a=4」(変数aに数値4を代入)のような代入命令も、じつはコピー命令である。なぜなら、変数aの中身を記録するためのアドレスに、4をコピーするからである。(要するに、代入命令も命令「MOV」で実現できる。)
参考: さまざまなプログラミング言語[編集]
プログラミング言語の種類は、さまざまである。 実務で、用途に沿ったプログラミング言語が用いられる。
たとえば、ウェブアプリケーションの用途では、「PHP」(ピー エイチ ピー)あるいは「Perl」(パール)や「Python」(パイソン)・「Ruby」(ルビー)・「Java[† 1]」(ジャバ)・「Go」(ゴー)などのプログラミング言語が用いられる。 ウェブページのプログラミングでは、「JavaScript[† 1]」(ジャバ スクリプト)などのプログラミング言語が用いられる。 また、オフィススイートなどのアプリケーションでは「マクロ言語」や「VBA」の様な簡易言語が用いられるが、保守性などの理由から TypeScript などの相対的に高度なスクリプティング言語が用いられることもある。 組み込みソフトウェアなどでは、「C言語」・「C++」(シープラスプラス)あるいはアセンブリ言語などのプログラミング言語が用いられる。
※ 範囲外: システムコール[編集]
※ 主にパソコンの話題。
一般に、オペレーティングシステムが他の企業の製品などに変わってしまえば、アプリケーションは動作しなくなる。
たとえば、マイクロソフト社のオペレーティングシステムwindows向けに作られたアプリケーションの実行ファイルの多くは、アップル社のオペレーティングシステム Mac OS(マック オーエス)の上では動作しない。また、windows向けアプリケーションの実行ファイルの多くは、オープンソースOSのLinux(リナックス)上でも動作しない。
同様に、Linux 向けに作成されたアプリケーションの実行ファイルの多くは、 windows上 やMac OS上では、動作しない。
なぜ、こうなるのか?
アプリケーションは、ハードウェアを制御しやすいように機械語に変換してあるのに、なぜ、特定のオペレーティングシステムが必要になるのか?
実は、世間のアプリケーションのほとんどは、OSがアプリケーション向けに提供する機能(一般に「API」(エーピーアイ、application programming interface)という)を利用しているだけである。
そして、アプリケーションのプログラムの内容は、そのOSの提供する複数の機能(API)を、組み合わせて、目的の処理を作っているだけである。
アプリケーションの動作内容を、プロセッサが理解出来るように翻訳することが、ほとんどの場合のアプリケーションでのコンパイルの目的である。
アプリケーションは顧客であり、OSがサービス提供者である。アプリケーションは単に、サービス提供者であるOSに、要望を提出しているだけにすぎない。
そしてOSは、読み込んだアプリケーション動作要望を実現するため、プロセッサなど各種資源の調整を行い要求されたサービスを実施する。
アプリケーションが各種サービスをOSに依頼するように、OSの機能をアプリケーションが依頼することをシステムコールという。
メモリの操作やCPUの操作などの、OSの機能の中枢のプログラムのことをカーネル(kernel)という。
主記憶装置と補助記憶装置[編集]
- ※ これは組み込みマイコンでもパソコンでも共通する話題。
メモリ基板のように、CPUとデータを直接やりとりするためのデータを記憶している記憶装置のことを、主記憶装置という。メモリ基板は主記憶装置である。
いっぽう、ハードディスクは補助記憶装置である。補助記憶装置となるものは、ハードディスクのほかにも、CDやDVDなどがある。
なぜ、メモリだけ特別に「主記憶装置」と区別するのかというと、CPUとデータを直接やりとりするのはメモリ基板だから、である。
ファミコンにはハードディスクは無かった |
|
いっぽう、ハードディスクは、CPUとは直接はデータをやりとりしない。
ハードディスクのデータをCPUで処理したい場合、まずハードディスクのデータをメモリに読みこみ、それからCPUでメモリのデータを1つずつ処理するという方法である。つまり、メモリを仲介して、間接的にハードディスクのデータを処理するという方法が用いられる。
CDやDVDのデータを処理する場合も同様に、メモリを仲介して処理する方式である。なので、ハードディスクもCD、DVDもまとめて補助記憶装置に分類される。
- (※ 参考。範囲外。 :) OSの中には、ハードディスクなどの補助記憶装置に、ユーザー(利用者であるアナタ)がデータ書き込みを命令した際、じつはスグには書き込みが実行されずに、いったんメモリ上に記録命令の予定を確保してから、あとから、動作待ちの時などに、OSが自動的に記録を実行する方式のものもある。Windowsなども、そうなっている。一般に、ハードディスクなど補助記憶装置の処理速度は、メモリよりも速度が低い。なので、このように書き込み処理作業を後回しにする仕組みを採用しているOSもある。
- このようなOSでは、まだハードディスク書き込みが終わってないのにかかわらず、ユーザの視点からは、あたかもハードディスク書き込みが高速に終わったかのように見える場合もある。
- パソコンの勉強では、OSの画面表示の内容と、実際に実行された処理の内容とが、実は あまり一致してない場合もある事に、気をつける必要がある。OSの画面表示の内容は、初心者向けに、だいぶ意訳をされてて、あまり正確でない内容が表示されている場合もある。
- 例えば(データ破損の恐れもあるので、オススメできない行為だが)ウィンドウズOSに、外付けハードディスクへの書き込み命令を指示したあと、ウィンドウズでは書き込み完了のアイコンがすぐに出るので、その直後にすぐにパソコン本体の電源ボタンを物理的に押して電源を落とすと、実はまだハードディスクへの書き込みは実行されておらず、再起動後に外付けハードディスクの内部データを閲覧しても、さきほど書き込み命令をしたデータがまったく存在しない場合もある。
じつはCPU以外にも演算処理装置のICチップが、昔のパソコンには、あった |
|
なお、パソコンのマザーボードには、そのパソコンの動作監視用のために温度や電圧などを測定して制御する監視用の専用チップも入っており、そのマザーボード監視用の専用チップのことをサービスプロセッサという。(※ 工業高校の科目『ハードウェア技術』で、ここまで習う。)
※ 範囲外[編集]
クロック信号の発生方法[編集]
- (※ 普通科の範囲外)
フリップフロップの教科書などを見ると、前提としてクロック信号が存在しているのだが、そもそもクロック信号は、どうやってつくるのだろうか?
CPUのクロック信号の発振方法は、「水晶発振子」または「セラミック発振子」といった電子部品を使って、クロック信号を発生させる。(「セラミック発振子」でネット検索すれば、電子部品メーカーのホームページなどが出てくるので、それを読むのが、理解には手っ取り早い。) 一般に、IC(集積回路)やLSIでは、水晶振動子やセラミック発振子を用いて、高いクロック周波数を発生させる。(※ 参考文献: 電波新聞社『電子回路入門講座』、見城尚志・高橋久、2012年第1版10刷、235ページ)
ハードウェアデバイスを動かす仕組み[編集]
パソコンに接続された外付けハードディスクやディスプレイモニターなど、いろんなハードウェアがありますが、これらはどういう仕組みで制御されてるのでしょうか?
詳しい仕組みは企業側が非公開にしていますが、一般には、機械語で制御してると考えられています。
つまり、パソコンから、たとえば「1101 0100」などの信号が送られてきて、ハードウェアは単に、送られた信号にもとづいて、動作をしているだけです。
では、そのような動作をできるするためには、どうすればいいでしょうか?
とりあえず、読者は中学校でロボット車を制御する原理を習ったと思うので、ここwikibooksでもロボット車の例で考えてみましょう。
説明の簡単化のため、デジタル制御のモーターとそのモータの接続されたタイヤがついた、ロボット車で考えましょう。
簡単のため、
- 正面方向にすすむためタイヤに接続したモータをモータAとし、
- 右方向に向きを変えるためのタイヤに接続したモータをモータBとし、
- 左方向に接続するためのタイヤに接続したモータをモータCとし、
- 後ろ方向に接続するためのタイヤに接続したモータをモータD
としましょう。
こうすれば、パソコンはロボット車にどのモータを動かすかの指令を送るだけで、車を前後左右に自由に動かせます。
(※ 実際には、正面方向に進むためのモータと、後ろ方向に進むためのモータとは、ひとつのモータに流す電流の向きを変えれば前後の両方にも使えるだろうから、1つのモータでも可能かもしれない。同様に左右のモータも、1つのモータでも可能かもしれない。よって、前後用に1つのモータと、左右用に1つのモータとで、合計2つのモータで対応可能かもいれない。
だが、本書では、説明の簡単化のため、各方向ごとに4つのモータを使うことにしよう。)
これを機械語の視点で考えてみましょう。
まず、ロボット車の設計者は(※ あなたが、仮に、中学生用の技術家庭科のためのロボット車の実技教材を設計する企業の技術者だったと仮定しよう)、4つあるモータのうち、どのモータを動かすかを、機械度で指定しなければなりません。
そのため、下記のように、まずは仕様を決めて、モータと機械語を対応させる必要があります。
- どのモータも動かさない 000
- モータA 001
- モータB 010
- モータC 011
- モータD 100
少なくとも、5つの命令が必要そうです。
なお、この仕組みだけだと、「モータAとモータBを同時に動かす」という事ができません。ですが、簡単のため、とりあえず、ひとつづつモータを動かす仕組みにしましょう。
さて、モータを何秒間、どの程度の強さで具体的にどのていど動かすかは、モータの番号だけでは不明です。
とりあえず、モータの強さを「弱、中、強」の3段階にしましょう。きっと、モーターに長す電流の大きさを3段階に設定しとけば、モータの出力の強さも三段階に分けられるでしょう。
機械語は
- モータの出力なし 00
- 出力は弱 01
- 出力は中 10
- 出力は強 11
としましょう。
さて、「ロボット車の前方やや右側にある目的地につくため、とりあえずモータを強度『中』で、とりあえず15秒間ほど、前進させたい」としましょう。
どうすればいいか、考えましょう。
とりあえず、「何秒間、モータを動かすか」というのも命令できるように設計する必要がありそうです。
とりあえず1秒単位で走行時間をセットできるように設計したとしましょう。
作業「ロボット車の前方やや右側にある目的地につくため、とりあえずモータを強度『中』で、とりあえず15秒間ほど、前進させたい」を実行するには、
- 走行時間は「15」秒、
- 強度は「中」
- 方向は「前進」
のように、作業を分解する必要があります。
そして、この作業を機械語に(設計者が)翻訳する必要があります。翻訳すると、
- 走行時間は機械語「0000 1110」(2進数で15に対応)、
- 強度は「01」(中)
- 方向は「001」(モータA)
のようになります。
ハード側の視点では、まず、 どの ハードを制御するかの命令が必要なので、
- 方向は「001」(モータA)
という情報がまっさきに必要です。
つづいて、出力の強さを決める必要があるでしょう。そのあとに、その強さで何秒間動かすかの情報が必要でしょう。
つまり、ハード側からすると、情報を知りたい順序は、
- 方向は「001」(モータA)
- 強度は「01」(中)
- 走行時間は機械語「0000 1110」(2進数で15に対応)、
のような順序になります。
もし、これを機械語にそのまま並べると、
- 「0010100001110」
となりますが、よみづらいので、とりあえず
- 「001 01 0000 1110」
としましょう。
しかし、これでも、3桁の「001」と2桁の「01」と8桁の「0000 1110」が混ざってて分かりづらいので、
4桁づつに
- 「0001 0001 0000 1110」
という機械語を送ることにしましょう。
そのためには、まず、モータの機械語の設計を
- どのモータも動かさない 0000
- モータA 0001
- モータB 0010
- モータC 0011
- モータD 0100
のように修正する必要があります。
また、モータ出力強度の機械語も修正し、
- モータの出力なし 0000
- 出力は「弱」 0001
- 出力は「中」 0010
- 出力は「強」 0011
としましょう。
こうすれば、
- 「0001 0001 0000 1110」
の信号を送ることによって、このロボット車は作業「ロボット車の前方やや右側にある目的地につくため、とりあえずモータを強度『中』で、とりあえず15秒間ほど、前進させたい」を実行できます。
上述のように、ロボットに命令をする場合には、設計者が、作業を機械語で処理できるように、設計する必要があります。
一般に、アセンブラには、機械語の信号をパソコンなどのポートから出力する機能があります(OUT命令というのがある)。それを使って、原理的には信号を出力できますので、上述のような制御もできます。(というか、そうでないとパソコン周辺装置などを製造しているハードメーカー企業がデバイスドライバを作れない)
- ^ 後閑哲也『たのしくできるPIC電子工作』、東京電機大学出版局、2003年3月20日、第1版9刷発行、56ページ ISBN9784501320508