これまで、4回にわたってマイコンの機能を使ったプログラミングを行ってきました。マイコンが便利な周辺機能を内蔵し、さまざまな要求に応える能力があることを感じていただけたと思います。マイコンを有効に動かすにはプログラムが欠かせませんが、そもそも、このプログラムはどのように動いているのでしょうか。今回から2回連続で、マイコンとプログラムの関係を解説します。

マイコンのメモリに注目

これまで、ルネサスのマイコン「RX63N」を搭載したGR-SAKURAボードのプログラミングを、Webコンパイラを使って行ってきました。コンパイラでビルドしたプログラム(オブジェクトコード)を、まるでUSBメモリへの書き込みのようにGR-SAKURAに転送して実行していました。さて、ここで疑問です。マイコンに書き込まれた(転送された)プログラムは、いったいどこに収まっているのでしょうか、また、プログラムはどのように実行されるのでしょうか。これらの疑問を解きながら、マイコンとプログラミングを理解しましょう。

まずはメモリ、メインと外部の2つの役割

プログラムやデータを憶える(収める)場所がメモリです。メモリには以下の二種類あります。

メインメモリ
CPUが直接アクセスできるメモリで、実行中のプログラムやデータが収められる
外部メモリ(補助メモリ、二次メモリ)
CPUから直接のアクセスはできず、USBやシリアル、パラレルの各種I/Oを通じてアクセスし、現在実行中(処理中)ではないアプリやデータが収められる

外部メモリにあるプログラムは、メインメモリに転送してから実行されます。

マイコンのメモリを示すとき、ROM(Read Only Memory:読み出し専用メモリ)、RAM(Random Access Memory:書き換えが可能メモリ)といったものが出てきますが、メモリの性質を示した言葉であって、メモリの役割には関係ありません。( マイコン入門(1)マイコンの基本構成、動作を参照

アドレス空間(メモリ空間)

CPUが直接読み書きできる、すべての空間を「アドレス空間(または、メモリ空間)」と呼びます。このアドレス空間は、1バイトごとに番号が振られています。この番号を「番地(アドレス)」と呼び、一般に16進数で表記されます。上で解説したメインメモリは、すべてアドレス空間に含まれます。

マイコンのCPUは用途に応じて、4ビットや8ビット、16ビット、32ビットが開発されてきました。GR-SAKURAに使われている「RX63N」マイコンは32ビットのCPUを搭載しており、32ビットマイコンとも呼ばれます。では、マイコンの持つアドレス空間の容量はどのくらいでしょうか。RX63Nの場合は32ビットCPUなので、最大で約40億(2の32乗)の番地を指定できます。正確には4,294,967,296(4x1024x1024x1024)個の番地です。1つの番地に1バイトを記憶させられるので、この場合、「4GB(ギガバイト)のアドレス空間」を持っているとも表現されます(コラム「コンピュータの単位」参照)。アドレス空間の容量が大きければ、大容量メモリの搭載が可能になり、プログラムのサイズにも余裕を持つことができます。より高機能なアプリケーションの実現が可能になるわけです。

32ビットCPUが持つ、4Gバイトのアドレス空間の表記例を図1に示しました。左端にアドレスを16進数で記しています(コラム「アドレス表記の16進数って何?」参照)。一つの列に4バイト(=32ビット)を収めるので、左端に記されるアドレスは4番地ずつ飛んだ値になります。

図1:アドレス空間と表記例

図1:アドレス空間と表記例

コンピュータの単位、ビットとバイト、メガ、ギガ、テラ

データの基本単位はビット(b=bit)で、1つのビットは"0"か"1"かの値をとります。8ビットをまとめて扱うとき、1バイト(B=Byte)と呼ばれる。例えば、3バイト(3×8ビット)は24ビットと同じことです。

パソコンのストレージ機器の容量に使われる単位として、KB(キロバイト)、MB(メガバイト)、GB(ギガバイト)、TB(テラバイト)はなじみがありますね。一般的に、1GB=1000MBと言ったり、そのように表示したりする場合もありますが、コンピュータの世界では単位は1000倍ごとではなく、1024倍(2の10乗)ごとに置かれるので正確には次のようになります。

  • 1KB(キロバイト)=2の10乗=1,024バイト
  • 1MB(メガバイト)=1,024KB=2の20乗=1,048,576バイト
  • 1GB(ギガバイト)=1,024MB=2の30乗=1,073,741,824バイト
  • 1TB(テラバイト)=1,024GB=2の40乗=1,099,511,627,776バイト

アドレス表記の16進数って何?

アドレス空間内の番地は、16進数を使って表記される。たとえば、16ビット(2の16乗)の広さを持つアドレス空間では、10進数での表記なら「0番地から65535番地」となるが、16進数表記では「0h番地からFFFFh番地」となる。10進数では、ひとつの桁で取る値は0から9だが、16進数では0からF(10進数の15相当)の値が入る。16進数で表した数は、最後に「h」を置いて16進表記である事を明示する。

decimal-hexadecimal

プログラムはどこにある?(ベクタテーブル)

では、プログラムは、アドレス空間のどこに置かれて、どのように動き始めるのでしょうか。マイコンは、リセットの後に、一番初めのプログラムの実行を開始します。リセットは、電源投入時やリセット信号を受信したときなどに起きます。実は、この「一番初めのプログラムの実行を開始する」という処理には、次に示す二つの方法があります。

プログラムの実行を始めるときに、実行開始番地を固定にするCPUと、可変にするCPUです。

固定にするCPUでは、多くが0番地(アドレス空間中の最も小さいアドレス)から実行を始めます。ここがプログラムの開始地点です。また、0番地に「次に実行する番地は○○番地」といったジャンプ命令を書き込んでおき、「○○番地」の部分にプログラムを置くこともあります。「○○番地」の部分を書き換えれば、開始番地を可変にしたと同様な効果が得られます。

可変にするCPUは、「ベクタテーブル」という部分に開始番地を書き込みます(図2)。ベクタテーブルは、アドレス空間の中のさまざまな開始番地ばかりを格納した特定の領域の名前です。一般には、アドレス空間中の最も大きなアドレス部分に置きます。

図2:RX63Nシリーズのベクタテーブル

図2:RX63Nシリーズのベクタテーブル

RX63Nの場合、アドレスは32ビットで示しますから、これを格納するためには4バイトを要します。図3の「リセット」の部分の意味はFFFFFFFCh番地からFFFFFFFFh番地の4バイトにプログラムの開始番地を収めるということです。CPUはリセット後にここに収められた番地を読み取り、記された番地から実行を開始します。ベクタテーブルに書かれるのは、リセット後の開始番地だけではありません。割り込みが起きた際のプログラム開始番地や、例外処理のための開始番地などがこのテーブルに収められています。割り込みや例外処理といった複数の事柄の開始番地も収めているので「テーブル(表)」と呼ばれるのでしょう。

ベクタテーブルを使ったプログラムの処理をイメージしましょう。下の図3では、例としてノンマスカブル割り込み(NMI)(*1)が発生した時の処理の流れを示しました。

  1. NMIが発生すると、
  2. ベクタテーブルのNMI部分に書かれた開始番地(この例では10000000h)を読み、
  3. 読んだ番地(10000000h)にあるNMI処理プログラムを開始します。

図3:ベクタテーブルを使った処理の流れ

図3:ベクタテーブルを使った処理の流れ


(*1)ノンマスカブル割り込み(NMI):ノンマスカブルとは禁止することができないことを意味します。割り込み要求があれば、CPUは無条件で割り込み処理を行います。例えば、ウォッチドッグタイマによる割り込みに使用されます。ウォッチドックタイマについては、本連載の第2回タイマ編で解説しています。

 

このように、プログラムの開始番地を可変にするCPUでは、ベクタテーブルに書き込むことで割り込み処理の開始番地を指定できるので、割り込み処理プログラムをアドレス空間の中で自由に配置できるという特徴があります。

今回は、CPUのアドレス空間と周辺機能の関係、そしてプログラムの実行がどこから始まるかを解説しました。マイコンも32ビット処理となると、非常に広大なアドレス空間を使うことができます。メモリは貴重な資源であるため、ここに収めるプログラムは小さく作ることが大切ですが、アドレス空間が16ビットの頃よりは余裕を持てるようになりました。プログラム短縮のために、アクロバティックな書き方をする必要は無くなり、読みやすさを念頭に置きつつプログラムを記述できるようになりました。

次回は、プログラムを実行中に起きる処理とメモリの関係を解き明かし、マイコンの効率的動作を理解します。

「周辺機能」を学ぼう

  1. GPIO
  2. タイマ
  3. シリアル通信
  4. 割り込み
  5. プログラミング(前編)
  6. プログラミング(後編)