
コンピューティングにおいて、メモリ アドレスとは、ソフトウェアとハードウェアの両方で使用されるメモリ内の特定のメモリ位置への参照です。[ 1 ]これらのアドレスは固定長の数字列であり、通常は符号なし整数として表示および処理されます。この数値表現は、CPU の機能 (命令ポインタやインクリメンタルアドレス レジスタなど) に基づいています。プログラミング言語の構造では、メモリを配列のように扱うことがよくあります。
デジタルコンピュータのメインメモリは、それぞれ固有の物理アドレス(特定のコード)で識別される多数のメモリ位置で構成されています。CPUやその他のデバイスは、これらのコードを使用して対応するメモリ位置にアクセスできます。一般的に、システムソフトウェア(BIOS、オペレーティングシステム、メモリテスターなどの専用ユーティリティプログラムなど)のみが、マシンコード命令またはプロセッサレジスタを使用して物理メモリに直接アクセスします。これらの命令は、CPUにメモリコントローラと呼ばれるハードウェアコンポーネントとやり取りするように指示します。メモリコントローラは、メモリバスまたはシステムバス、あるいは個別の制御バス、アドレスバス、データバスを介してメモリへのアクセスを管理し、プログラムのコマンドを実行します。メモリコントローラによって管理されるバスは、それぞれがバイナリ数字(ビット)を表す複数の並列線で構成されています。
コンピュータプログラムは、メモリアドレスを使用してマシンコードを実行し、データを格納および取得します。初期のコンピュータでは、論理アドレス(プログラムが使用するアドレス)と物理アドレス(ハードウェアメモリ内の実際の場所)は同じでした。しかし、仮想メモリの導入により、ほとんどのアプリケーションプログラムは物理アドレスを直接扱うことはなくなりました。代わりに、コンピュータのメモリ管理ユニット(MMU)とオペレーティングシステムのメモリマッピング機構によって物理アドレスに変換される論理アドレスまたは仮想アドレスを使用します。
現代のコンピュータのほとんどはバイトアドレス指定方式を採用しています。各アドレスは、8ビットのバイト(オクテット)からなる単一の記憶領域を識別します。1バイトを超えるデータは、連続するアドレスのシーケンスに格納できます。ワードアドレス指定方式を採用しているコンピュータも存在し、その場合、最小の記憶領域はプロセッサのワード単位となります。[ a ]例えば、Data General Nova ミニコンピュータ、Texas Instruments TMS9900およびNational Semiconductor IMP-16マイクロコンピュータは 16 ビットワードを使用しており、 36 ビットワードアドレッシングを使用する古いメインフレームコンピュータも多数存在します(例えば、15 ビットワードアドレスで 2 15 36 ビットワードのアドレス空間、約 128 キロバイトのストレージを提供するIBM 7090や、 18 ビットワードアドレスで 2 18 36 ビットワードのアドレス空間、約 1 メガバイトのストレージを提供するDEC PDP-6 / PDP-10など)。メモリのアドレス指定範囲は、アドレスに使用されるバスのビットサイズに依存します。使用されるビット数が多いほど、コンピュータで使用できるアドレス数も多くなります。例えば、20ビットのアドレスバスを持つ8ビットバイトアドレス指定可能なマシン(Intel 8086など)は、 2²⁰(1,048,576)個のメモリ位置、つまり1 MiBのメモリをアドレス指定できます。一方、32ビットバス(Intel 80386など)は2³²(4,294,967,296)個の位置、つまり4 GiBのアドレス空間をアドレス指定できます。これに対し、18ビットのアドレスバスを持つ36ビットワードアドレス指定可能なマシンは、2¹⁸ ( 262,144)個の36ビット位置(9,437,184ビット)しかアドレス指定できません。これは1,179,648個の8ビットバイト、つまり1152 KiB 、または1.125 MiBに相当し、8086よりわずかに多いだけです。
ごく一部の旧型マシンはビットアドレス指定が可能です。例えば、IBM 7030「Stretch」の可変フィールド長(VFL)命令では、ビットアドレス、1~8バイトのサイズ、およびフィールド長を指定します。
古いコンピュータ(10進数コンピュータ)の中には、 10進数でアドレス指定できるものがあります。たとえば、IBM 1620の磁気コアメモリの各アドレスは、パリティビット、フラグビット、および 4 つの数値ビットからなる6 ビットのバイナリ符号化 10 進数 1 桁を識別します。[ 2 ] 1620 は 5 桁の 10 進数アドレスを使用していたため、理論上は最大で 99,999 のアドレスが使用可能でした。実際には、CPU は 20,000 のメモリ位置をサポートし、オプションで最大 2 つの外部メモリユニットを追加でき、それぞれが 20,000 アドレスをサポートし、合計で 60,000 (00000–59999) になりました。
古いコンピュータの中には、6ビットBCD文字が2ビットのゾーンと4ビットの数字を含む文字アドレス指定方式を採用しているものがあり、アドレス内の文字は0~9を表す数字のみを持ちます。通常、ゾーンビットの一部はアドレスの一部となり、残りはインデックスレジスタや間接アドレスなどの他の用途に使用されます。[ 3 ]
古いコンピュータの中には、10進ワードアドレス指定が可能なものがあり、通常は4桁のアドレスを使用します。[ 4 ]一部のマシンでは、アドレスフィールドがインデックスレジスタも選択するため、可能なアドレスの範囲が制限されます。[ 5 ]
ワードサイズとは、コンピュータアーキテクチャの特性の一つで、CPUが一度に処理できるビット数を表します。組み込みシステムを含む現代のプロセッサは、通常8、16、24、32、または64ビットのワードサイズを持ち、現在主流の汎用コンピュータのほとんどは32または64ビットを使用しています。歴史的には、8、9、10、12、18、24、36、39、40、48、60ビットなど、さまざまなサイズが使用されてきました。
現代のコンピュータのワードサイズについて言及する場合、多くの場合、そのコンピュータのアドレス空間のサイズも同時に表しています。例えば、「32ビット」と呼ばれるコンピュータは、通常32ビットのメモリアドレスを許容します。バイトアドレス指定可能な32ビットコンピュータは、2³² = 4,294,967,296バイト、つまり4ギビバイト(GiB)のメモリをアドレス指定できます。これにより、1つのメモリアドレスを1ワードに効率的に格納できます。
しかし、これは常に当てはまるわけではありません。コンピュータは、ワードサイズよりも大きいまたは小さいメモリ アドレスを持つことができます。たとえば、MOS Technology 6502などの多くの8 ビットプロセッサは16 ビット アドレスをサポートしていました。そうでなければ、メモリ アドレス指定は 256 バイトに制限されていました。16ビット Intel 8088 および Intel 8086 は、セグメンテーションにより 20 ビット アドレス指定をサポートし、64 KiB ではなく 1 MiB のメモリにアクセスできました。Pentium Pro 以降のすべての Intel Pentium プロセッサには、36 ビットの物理アドレスを32ビットの仮想アドレスにマッピングする物理アドレス拡張(PAE)が含まれています。たとえば36 ビットプロセッサ上の初期のLISP実装の多くは、 consの結果として、ワードあたり 2 つのアドレスを保持していました。初期のプロセッサの中には、命令ワードあたり 2 つ、さらには 3 つのアドレスを保持していたものもありました。
理論上、最新のバイトアドレス指定可能な64ビットコンピュータは2⁶⁴バイト(16エクサバイト)をアドレス指定できますが、実際にはメモリの容量はCPU、メモリコントローラ、またはプリント基板の設計(例えば、物理的なメモリコネクタの数やはんだ付けされたメモリの量)によって制限されます。
プログラム内蔵型コンピュータの各メモリ位置には、何らかのバイナリ数または10進数 が格納されている。そのメモリ位置が何らかのデータ型のデータとして解釈されるか、あるいは命令として解釈されるか、またどのように使用されるかは、そのメモリ位置を取得および操作する命令によって決定される。
初期のプログラマーの中には、メモリが高価だった時代にメモリを節約する方法として、命令とデータをワードにまとめる者もいました。Manchester Mark 1は 40 ビットのワード内に小さなデータを格納するスペースがあり、プロセッサはワードの中央の小さなセクションを無視していたため、それが追加のデータ格納領域としてよく利用されました。ウイルスなどの自己複製プログラムは、自身をデータとして扱う場合と命令として扱う場合があります。自己修正コードは、数バイトの節約に対してテストとメンテナンスが不釣り合いに難しくなり、コンパイラやプロセッサがマシンの状態について仮定しているために誤った結果をもたらす可能性もあるため、現在では一般的に非推奨となっていますが、細心の注意を払って意図的に使用されることもあります。
現代のマルチタスク環境では、アプリケーションプロセスは通常、アドレス空間(または複数のアドレス空間)内に、以下の種類のメモリチャンクを保持します。
アドレス空間の一部は、全くマッピングされない場合があります。
システムによっては、マシンコード、定数、データが異なる場所に配置され、アドレスサイズも異なる「分割型」メモリアーキテクチャを採用しているものがあります。例えば、 PIC18マイクロコントローラは、フラッシュメモリ内のマシンコードと定数をアドレス指定するための21ビットプログラムカウンタと、SRAM内のデータをアドレス指定するための12ビットアドレスレジスタを備えています。
コンピュータプログラムは明示的に指定されたアドレスにアクセスできます。低レベルプログラミングでは、これは通常、絶対アドレス、または場合によっては特定のアドレスであり、高水準言語ではポインタデータ型として知られています。しかし、プログラムは、別の場所(ベースアドレス)からの相対的な位置を指定する相対アドレスアドレッシングモードは他にも多数あります。
論理アドレスを物理メモリと仮想メモリにマッピングすると、間接参照のレベルが複数追加されます。詳細は下記を参照してください。
多くのプログラマーは、コード空間とデータ空間(上記参照)や物理メモリと仮想メモリ(上記参照)の区別がないようなメモリのアドレス指定を好みます。つまり、数値的に同一のポインタは、RAMのまったく同じバイトを参照します。
しかし、初期のコンピュータの多くはこのようなフラットなメモリモデルをサポートしていませんでした。特に、ハーバードアーキテクチャのマシンでは、プログラム格納領域とデータ格納領域を完全に分離する必要がありました。多くの最新のDSP(例えばMotorola 56000)は、プログラム格納領域、係数格納領域、データ格納領域という3つの独立した格納領域を備えています。よく使用される命令の中には、これら3つの領域すべてから同時にフェッチするものがあり、格納領域の数が少ないと(たとえ合計の格納容量が同じであっても)、これらの命令の実行速度が低下します。
初期のx86プロセッサは、メモリセグメントと、そのセグメント内のオフセットという2つの数値の組み合わせに基づいてアドレスを指定するセグメントメモリモデルを使用していた。
一部のセグメントは、命令専用のコードセグメント、スタックセグメント、または通常のデータセグメントとして暗黙的に扱われます。用途は異なりますが、セグメントごとにメモリ保護が異なるわけではありません。フラットメモリモデルでは、すべてのセグメント(セグメントレジスタ)は一般的にゼロに設定され、オフセットのみが可変です。
IBM は360/65および360/67で、プレフィックスと呼ばれる概念を導入しました。[ 6 ]プレフィックスは、マルチプロセッサ システムの各 CPU に割り当てられた一意のプレフィックスを使用して、リアル モードのアドレスと動的アドレス変換によって生成されたアドレスに適用されるアドレス変換のレベルです。360/65、360/67、およびz/Architectureより前のすべての後継システムでは、4096 バイトのストレージ ブロックを CPU に割り当てられた別のブロックと論理的に交換します。z/Architecture では、[ 7 ]プレフィックスは 8196 バイトのブロックで動作します。IBM はこれらのシステムのアドレスを次のように分類しています。[ 8 ]
360/65、DAT非搭載のS/370モデル、およびアドレス変換をオフにして動作させている場合、フラットな実アドレス空間とフラットな絶対アドレス空間のみが存在します。
360/67、S/370、およびS/390までの後継機種では、アドレス変換を有効にして実行する場合、アドレスにはセグメント番号、ページ番号、およびオフセットが含まれます。初期モデルでは2 KiBと4 KiBの両方のページサイズがサポートされていましたが、後期モデルでは4 KiBのみがサポートされました。IBMは後に、プライマリアドレス空間とセカンダリアドレス空間間でデータを移動する命令を追加しました。
S/370-XAは31ビットアドレスを追加したが、セグメント/ページ/オフセットの階層構造は維持し、ページサイズは4KiBとした。
ESA/370では、16個のアクセスレジスタ(AR)とARアクセス制御モードが追加されました。このモードでは、選択されたARによって指定されたアドレス空間を使用して31ビットのアドレスが変換されます。
z/Architectureは、 64ビットの仮想アドレス、実アドレス、および絶対アドレスをサポートし、マルチレベルのページテーブルに対応しています。
再配置手順は、ストレージの最初の4,096バイトに適用されます。この領域にはすべての永続ストレージ割り当てが含まれており、一般的に監視プログラムにとって特別な意味を持ちます。再配置は、上位12ビットがゼロに設定された12ビットのプレフィックスを各アドレスに挿入することによって実行され、したがって、位置0~4095に関係します。
プレフィックスを使用すると、割り当てられたストレージ ロケーションを含む実アドレスのブロックを、各 CPU の絶対ストレージ内の別のブロックに割り当てることができ、これにより、メイン ストレージを共有する複数の CPU が、特に割り込み処理において、干渉を最小限に抑えながら同時に動作できるようになります。