めざせ4004! IC24個で電卓用CPUを作ってみた: Chapter 2-3 インデックスレジスタに求められる機能

 インデックスレジスタを搭載するのは良いとして、そのインデックスレジスタにはどのような機能が求められるでしょうか? 先ほどのC言語のサンプルを元に検討してみましょう。説明を単純にするために1個のデータが1個のアドレスに格納されているものとします。C言語風に言うとchar型の配列だと思ってください。

Chapter 2-3-1 配列の場合

 ます配列です。以下のコードをご覧ください。

 

これを図に表すと図3のようになります。配列cxがRAMの0x10番地から0x16番地の範囲に存在しているとします。0x10番地にある15がcx[0]の内容、0x11番地にある13がcx[1]の内容、という具合です。

コード5では変数iの内容が1ですから、これを配列cxの添字として指定すると最終的なアドレスはcxのアドレスである0x10とiの内容である1を加算したもの、つまり0x11となります。 これをCPUで実行するには変数iをインデックスレジスタに割り当てた上で、配列cxのアドレスである0x10をオフセットとして指定します。

Chapter 2-3-2 ポインタの場合

 ポインタを使って直接RAM上のアドレスを指定する場合を検討します。

 ポインタは通常、ポインタの内容がそのままRAMのアドレスとなります。そのため図4のようにRAMへのアクセスは非常に簡単となります。

 実際のCPUではポインタをインデックスレジスタに割り当てれば良いでしょう。 重要なのはポインタのインクリメント(++)やデクリメント(–)を行う機能でしょう。これを実現するためにCPUにはインデックスレジスタに対する加減算回路が必要となります。

Chapter 2-3-3 構造体の場合

 次は構造体、特に構造体のポインタの場合です。

 

 構造体のポインタの場合、ポインタが指すのは構造体の先頭アドレスです。そのため構造体の各要素にアクセスするためには、ポインタの値に各要素までのオフセットを加算してRAM上のアドレスを求める必要があります。 上記コード7の構造体sxにはchar型の要素が2個、int型の要素が1個ありますが、これらの要素は先頭から順番にRAM上に配置されます。

 

 図5をご覧ください。構造体sxが0x10番地に配置されていて、各要素は0x10番地から順番に並んでいます。例えば要素aは構造体の先頭である0x10番地に配置され、オフセットは0となります。

 要素bの位置は要素aのサイズによって決まります。要素aのサイズは1語なので、要素bの位置は0x11番地となり、オフセットは1となります。

 同様に要素cは要素aとbのサイズから0x12番地に配置されます。つまりオフセットは2です。ただし要素cはint型であるため0x12番地から0x15番地までのアドレス4個分に配置されます[1]

 コード7のように、構造体のポインタspを使って構造体sxの要素bにアクセスする場合を考えてみましょう。あらかじめspにはsxのアドレスである0x10を代入しておきます。

 要素bにアクセスするためには、spの値に要素bのオフセットである1を加算します。すると結果は0x11となり、これが要素bのRAM上でのアドレスとなります。 これをCPUで実現するには、構造体のポインタspをインデックスレジスタに割り当てた上で、要素bのオフセットである1を加算してRAMアドレスとします。


[1] 話を簡単にするために、各要素のアライメントについては省略します。