プログラムカウンタ(、略してPC)とは、コンピュータがプログラムの実行順序のどこに存在するかを示すレジスタである。PCはインテルのx86およびItaniumマイクロプロセッサでは一般的に命令ポインタ (IP)と呼ばれるが、まれに命令アドレスレジスタ (IAR)、命令カウンタ、あるいは単に命令シーケンサーの一部とも呼ばれる。
通常、PCは命令をフェッチした後にインクリメントされ、次に実行される命令のメモリアドレス(またはそれを保存したポインタのメモリアドレス)が保存される。
普段プロセッサはメモリから順番通りに次の命令をフェッチするが、制御転送命令によりPCへ新しい値が設定されると実行順序が変化する。これらの制御転送命令には、分岐命令(時々ジャンプ命令と呼ばれる)、サブルーチン呼び出し、そしてreturn命令などがあり、ある条件判定の真偽に応じて実行順序を変えるようにコンピュータを従わせる。
分岐命令は、次に実行すべき命令をメモリのどの場所からフェッチするかを規定する。サブルーチン命令は分岐命令を呼び出すだけでなく、直前のPCの値をどこかへ保存する。return命令は、サブルーチン命令により保存されたPCの値を取り出しそれをPCへと戻し、サブルーチン呼び出し直後の命令から順番通りに実行を再開する。
ハードウェア実装 単純なCPUでは、PCは(「プログラムカウンタ」という用語の語源としての)デジタルカウンタである、さらにその場合、PCはハードウェアレジスタの中の1つかもしれない。の始まりはフェッチであり、これによってCPUはアドレスバスにPCの値を配置してそれをメモリに送信する。その送信を受けたメモリは、メモリ位置に存在する値を応答としてデータバスでCPUに送信する(これがプログラム内蔵方式モデルであり、単純なメモリ空間には実行命令と普通のデータの両方が含まれる)。CPUはフェッチが終わると次に実行へと遷移する。これによりCPUは応答として送信されたメモリの値に基づいて、何らかの動作を実行する。このサイクルのどこかで、次に実行する命令を異なるものとするようPCが修正される可能性がある(通常、PCはインクリメントされ、現在の命令メモリ位置の直後のメモリアドレスにある命令を次の命令として即座に開始する)。
PCは他のプロセッサレジスタのようにバイナリラッチのバンクであり、1つのラッチがPCの値の1ビットを表す。ビットの数(PCの幅)はプロセッサのアーキテクチャと関係がある。例えば「32ビット」CPUは32ビットを使いメモリを232個の単位として指定できる。プロセッサの中には、PCの幅がアドレス指定可能なメモリに依存するものもある。例えば、AVRマイクロコントローラの中には12ビットでラップアラウンドするものもある。
PCがバイナリカウンタの場合、パルスがPCのCOUNT UP入力であればインクリメントされ、パルスがPCのLOAD入力であればCPUが他の値をいくつか演算した結果をPCへロードするなどが行われる。
現在の命令を特定するため、PCはセグメントやページを特定する他のレジスタと組み合わされることもある。このアプローチでは関心のあるメモリ単位のほとんどが現在位置の近くにあると仮定することで、PCのビット数をより少なくできる。
機械アーキテクチャへの影響 通常、インクリメントするPCの使用は、コンピュータは通常順序通りに命令を実行することを前提としている。このようなPCはノイマン型アーキテクチャの主流である。そのため、プログラマは例え順序通りに実行すべきではないアルゴリズムであっても、順序通りに実行するように制御構造を書く。その結果として生じた「フォン・ノイマン・ボトルネック」により、並列計算の研究が導かれた。この研究成果には、PCを使用しない非ノイマン型やデータフローモデルなどがある。実行順序の順序を指定しない例としては、上層のプログラマによる希望の関数指定や、下層のプログラマによるコンビネータ論理使用の指定などがある。
並列計算の研究は、以下に示すような方法で従来のPCベースのCPUをより高速に動作させる方向へと導いた: CPU内の異なるハードウェアが複数の命令を異なるフェーズで同時実行するパイプライン処理。 単一の命令で複数の効果を達成するVery long instruction word (VLIW) アーキテクチャ。 アウト・オブ・オーダー実行を予測し、正規の順序通りではない実行のために次の命令を準備する技術。
高水準プログラミングにおける結果 現代の高水準プログラミング言語では未だに順序通りの実行モデルに従う。実際、プログラミングエラーを特定する一般的方法は、PC同様にプログラマの指が実行箇所を特定するという「手続き実行」で行う。高水準プログラミング言語は原則的に仮想マシンの機械語とされるが、それをハードウェアとして構築するにはあまりに複雑なため、代わりにエミュレータやインタプリタといったソフトウェアで構築する。
しかしながら新しいプログラミングモデルは、以下のように順序通りの実行プログラミングより優れている: マルチスレッドプログラムを書く場合、プログラマは他のスレッドの命令に対する個々の命令のタイミングを指定せずに、各スレッドを順序通りの命令実行として書くことができる。 イベント駆動型プログラミングでは、プログラマはイベントへ返信する命令の実行順序を、プログラム全体の実行順序を指定せずに書くことができる。 データフロープログラミングでは、プログラマは計算を行うの各セクションを、他のセクションに対するタイミングを指定せずに書くことができる。
関連項目 分岐予測 命令キャッシュ
命令パイプライン 命令レジスタ 命令スケジューリング
注釈
脚注