
プログラムカウンタ(PC)[ 1 ]は、プロセッサによってコンピュータプログラムがどこで実行されているかを格納するレジスタです。[ 2 ]また、 Intel x86およびItaniumマイクロプロセッサでは、命令ポインタ(IP)とも呼ばれ、命令アドレスレジスタ(IAR)[ 3 ] [ 1 ]、命令カウンタ[ 4 ]、または単に命令シーケンサの一部[ 5 ]と呼ばれることもあります。
通常、PC には命令のメモリ アドレスが格納されます。さらに、通常は命令のフェッチ後にインクリメントされ、したがって次に実行される命令を指します。 [ 6 ]フェッチ前にインクリメントするプロセッサの場合、PC は実行中の命令を指します。一部のプロセッサでは、PC は現在の命令からある程度離れた位置を指します。たとえば、ARM7では、プログラマから見える PC の値は命令のプリフェッチを反映しており、ARM ステートでは現在の命令のアドレスに 8 を加えた値、Thumb ステートでは 4 を加えた値として読み取られます。[ 7 ]最新のプロセッサでは、命令レベルの並列性とアウトオブオーダー実行により、プログラム内での実行位置が複雑になります。
デフォルトでは、プロセッサはメモリから命令を順次フェッチしますが、制御転送命令はPCに値を書き込むことで順序を変更します。分岐命令は、メモリ内の別の場所から次の命令をフェッチできるようにします。関数呼び出しは分岐するだけでなく、PCの値を保存します。戻り命令は、保存された値に分岐することでPCの値を復元し、呼び出しの次の命令から実行を再開します。何らかの条件の真偽に応じて実行される転送命令は、コンピュータが異なる状況下で異なる順序で実行できるようにします。
単純な中央処理装置(CPU) では、PC はデジタルカウンタ(「プログラムカウンタ」という用語の由来) であり、複数のハードウェアレジスタのいずれかになります。命令サイクル[ 8 ]はフェッチから始まります。フェッチでは、CPU は PC の値をアドレスバスに配置してメモリに送信します。メモリは、そのメモリ位置の内容をデータバスに送信することで応答します。(これは、単一のメモリ空間に実行可能な命令と通常のデータの両方が含まれるストアードプログラム方式のコンピュータモデルです。 [ 9 ] ) フェッチの後、CPU は実行に進み、取得したメモリの内容に基づいて何らかの処理を実行します。このサイクルのどこかの時点で、PC が変更され、次に実行される命令が別の命令になります (通常は、現在の命令の最後のメモリ位置の直後のメモリ アドレスから始まる命令が次の命令になるようにインクリメントされます)。
他のプロセッサレジスタと同様に、PCはバイナリラッチのバンクであり、各ラッチはPCの値の1ビットを表します。[ 10 ]ビット数(PCの幅)はプロセッサアーキテクチャに関係します。たとえば、「32ビット」CPUは、2³²ユニットのメモリをアドレス指定できるように32ビットを使用する場合があります。一部のプロセッサでは、プログラムカウンタの幅はアドレス指定可能なメモリに依存します。たとえば、一部のAVRマイクロコントローラは、 12ビット後にラップアラウンドするPCを備えています。[ 11 ]
PCがバイナリカウンタの場合、COUNT UP入力にパルスが印加されるとインクリメントされる場合もあれば、CPUが別の値を計算してLOAD入力にパルスを印加することでPCにロードされる場合もある。[ 12 ]
現在の命令を識別するために、プログラムカウンタ(PC)は、セグメントまたはページを識別する他のレジスタと組み合わせることができます。このアプローチでは、対象となるメモリユニットのほとんどが現在の近傍にあると仮定することで、より少ないビット数のPCを実現できます。
通常インクリメントする PC の使用は、コンピュータが通常線形の命令シーケンスを実行することを前提としています。このような PC はフォン ノイマン アーキテクチャの中心です。そのため、プログラマは、逐次である必要のないアルゴリズムであっても、逐次的な制御フローを記述します。結果として生じる「フォン ノイマン ボトルネック」は、並列コンピューティングの研究につながり、[ 13 ] PC を使用しない非フォン ノイマンまたはデータフロー モデルも含まれます。たとえば、逐次的なステップを指定する代わりに、高レベル プログラマは目的の機能を指定し、低レベル プログラマは組み合わせ論理を使用してこれを指定する可能性があります。
この研究は、従来のPC用CPUを高速化する方法にもつながり、以下のような成果が得られた。
現代の高級プログラミング言語は依然として逐次実行モデルに従っており、実際、プログラミングエラーを特定する一般的な方法は、プログラマーの指がPCのように実行ポイントを特定する「プロシージャ実行」です。高級言語は基本的に仮想マシンの機械語であり、[ 14 ]ハードウェアとして構築するには複雑すぎるため、ソフトウェアによってエミュレートまたは解釈されます。
しかし、新しいプログラミングモデルは、逐次実行プログラミングの枠を超えています。
現在実行中の命令のアドレスを格納することで、プログラムシーケンスを追跡するレジスタです。チップの電源投入時またはリセット時には、自動的にゼロがロードされます。各命令が実行されるたびに、PCはインクリメント(1ずつ増加)され、次の命令を指すようになります。
AT90S8515
の場合
、これは 12 ビットを意味し、4 K ワードまたは 8 K バイトに相当します。この仮定により、ROMの先頭から末尾、およびその逆方向への相対的な分岐が可能になります。厳密な算術演算を用いると、分岐外エラーが発生します。ここでは、ターゲットアドレスの計算結果であるキャリービットが破棄されるため、これらの分岐が機能します。[…] 上記のAT90S8515の場合、このオプションはアドレス空間全体を直接ジャンプする唯一の方法であるため、必要不可欠です。[…]