●CPUの動作原理と命令の実行
今度は具体的にCPUの動きを追って説明しましょう。このワークショップでは、基本的にZilog社のCPU、Z80を例に説明していきます。
CPUは命令を実行して動いていきます。電源を投入したら、メモリの頭から読み込んで動くと説明しましたので、メモリの先頭からつぎのようなデータが存在したとします。
番地 | データ(値) |
---|---|
0000h | 00h |
0001h | 3Eh |
0002h | 10h |
: : |
: : |
まず、CPUは当然0000h番地を読みます。そこに保存されている値は00hです。この場合CPUが動作して、はじめに読んだ値ですね。この場合、CPUはこのデータをCPUへの命令(命令コードまたはOP(オペレーション)コード)とみなし読み込みます。
そしてZ80のメーカー仕様書を見ると、
コード | オペレーション |
---|---|
00h | Non OP |
というような、仕様が記載されています。表のコードって言うのが命令に当たる部分で、オペレーションがそのコードならば、CPUがどのような動作をするのかを説明しているわけです。
この命令はノンオペレーションという命令で、CPUはなにもしません。(笑)
00hの命令がメモリ上に続けばなにもしないで、つぎの命令をどんどん読んでいきます。
蛇足ですけど、この命令もちゃんとしたCPUの命令です。結果的になにも起きない命令ですが、なにもしないってことを実行しているわけです。まわりくどい言い方ですけど、要するに、命令を読み込んで、なにもしないでつぎの処理へ行くっていう処理ですから、仕様書を見るとこの命令を実行するオーダー(実行に必要なクロック数)は4クロックです。たとえば400MHzCPUの場合、4クロックは10ns(ナノ秒)ですから、こんな命令がいっぱいあると、はっきり言ってクロックの無駄になるわけですね。
さて0000h番地が終わったのでつぎは0001h番地へ実行が移ります。同様に、CPUは次の実行コードを読みます。0001h番地のコードは3Ehです。仕様書では
コード | オペレーション |
---|---|
3Eh n |
A ← n |
というような記載になっています。
表の読み方ですが、nという表記は1バイトの値(データ)を意味し、AはAレジスタを意味します。
今度はオペレーションの部分で動作が説明されています。これは、←の方向へ値の転送が行われる転送命令(移動命令ともいう)と呼ばれるものです。この表の場合、Aレジスタに値nが設定されることを意味しています。
Z80の場合は、これをロード命令とも呼びます。インテル系のCPUであればムーブ命令と呼ばれ、動作は同じことなんですが、メーカーによって呼び方が違っています。
このことから、この命令が実行されるとCPUはAレジスタに値nを入れる動作をするわけです。
この表ではコードのところに3Ehとnが書かれています。これは3Ehが命令になり、nがその命令に必要なデータ(値)です。この3Ehという命令は2バイト命令と呼ばれ、この2バイトで一つの動作をします。先ほどのノーオペレーション命令はデータを必要としないため1バイトとなり1つで命令が終了しました。
このようにCPUは3Ehという命令を受けると、そのオペレーションに従い、次のアドレスにある1バイト、10hをAレジスタへセットします。そして実行後は0003hに実行が移ります。
番地 | データ | 認識 |
---|---|---|
0000h | 00h | コード |
0001h | 3Eh | コード データ |
0002h | 10h | |
: : |
: : |
このようなコードとデータの集まりがCPUを動かすプログラムとなります。このようにCPUへ直接送られる命令を記述したものを機械語(マシン語)と呼ばれるわけです。
●CPUで実際に計算させてみる
では、実際に計算をさせてみましょう。
10+20を計算させる場合の手順を紹介しましたが、まず、足し算を行う命令を見てみますと
コード | オペレーション |
---|---|
80h | A ← A+B |
のような命令があります。
これはAレジスタとBレジスタを足し、その結果がAレジスタへ入るという仕様になっています。
これを使うにはまずそれぞれのレジスタに計算したい値を入れなければいけません。そこで移動命令を使います。
コード | オペレーション |
---|---|
3Eh n |
A ← n |
06h n |
B ← n |
以上を元に計算させるプログラムを作ります。値の10と20は16進数にするとそれぞれ、0Ahと14hです。
番地 | データ | 動作 |
---|---|---|
0000h | 3Eh | A ← 10 |
0001h | 0Ah | |
0002h | 06h | B ← 20 |
0003h | 16h | |
0004h | 80h | A ← A+B |
これで機械語による足し算プログラムができました。