
コンピューティングにおいて、メモリアドレスとは、ソフトウェアとハードウェアの両方で使用されるメモリ内の特定のメモリ位置への参照です。[ 1 ]これらのアドレスは固定長の数字列であり、通常は符号なし整数として表示および処理されます。この数値表現は、CPUの機能(命令ポインタやインクリメンタルアドレスレジスタなど)に基づいています。プログラミング言語の構成要素は、メモリを配列のように扱うことがよくあります。
デジタルコンピュータのメインメモリは、多数のメモリ位置で構成され、各位置は一意の物理アドレス(特定のコード)で識別されます。 CPU やその他のデバイスは、これらのコードを使用して、対応するメモリ位置にアクセスできます。通常、システムソフトウェア(BIOS、オペレーティングシステム、メモリテスターなどの専用ユーティリティプログラムなど)のみが、マシンコード命令またはプロセッサレジスタを使用して物理メモリを直接アドレス指定します。これらの命令は、CPU にメモリコントローラと呼ばれるハードウェアコンポーネントと対話するように指示します。メモリコントローラは、メモリバスまたはシステムバス、または独立した制御バス、アドレスバス、およびデータバスを通じてメモリへのアクセスを管理し、プログラムのコマンドを実行します。 メモリコントローラによって管理されるバスは、それぞれが 2 進数(ビット)を表す複数の並列ラインで構成されています。
コンピュータプログラムは、メモリアドレスを用いてマシンコードを実行し、データを保存・取得します。初期のコンピュータでは、論理アドレス(プログラムが使用するアドレス)と物理アドレス(ハードウェアメモリ内の実際の位置)は同じでした。しかし、仮想メモリの導入により、ほとんどのアプリケーションプログラムは物理アドレスを直接扱うことはなくなりました。代わりに、論理アドレスまたは仮想アドレスを使用します。これらのアドレスは、コンピュータのメモリ管理ユニット(MMU)とオペレーティングシステムのメモリマッピング機構によって物理アドレスに変換されます。
現代のコンピュータのほとんどはバイトアドレス指定可能です。各アドレスは8ビットのバイト(オクテット)単位の記憶域を識別します。1バイトを超えるデータは、連続したアドレス列に格納できます。ワードアドレス指定可能なコンピュータも存在し、その場合、アドレス指定可能な最小記憶域単位はプロセッサのワードと全く同じです。[ a ]たとえば、Data General Nova ミニコンピュータ、Texas Instruments TMS9900およびNational Semiconductor IMP-16マイクロコンピュータは 16 ビットワードを使用していました。また、バイトアドレス指定ではなく、 36 ビットワードアドレス指定を使用する古いメインフレームコンピュータも多数あります(15 ビットワードアドレスのIBM 7090では、アドレス空間は 2 15 36 ビットワード、約 128 キロバイトのストレージ、 18 ビットワードアドレスのDEC PDP-6 / PDP-10では、アドレス空間は 2 18 36 ビットワード、約 1 メガバイトのストレージ)。メモリのアドレス指定の範囲は、アドレスに使用されるバスのビットサイズによって異なります。つまり、使用されるビット数が多いほど、コンピュータで使用できるアドレスが多くなります。例えば、20ビットアドレスバスを備えた8ビットバイトアドレス指定可能なマシン(例: Intel 8086 )は、2 20(1,048,576)個のメモリ位置、つまり1 MiBのメモリをアドレス指定できます。一方、32ビットバス(例:Intel 80386 )は、 2 32(4,294,967,296)個のメモリ位置、つまり4 GiBのアドレス空間をアドレス指定できます。一方、18ビットアドレスバスを備えた36ビットワードアドレス指定可能なマシンは、2 18(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ビットの2進化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の32乗= 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 つのアドレスを保持していました。
理論上は、バイト アドレス指定可能な最新の64 ビットコンピュータは264バイト (16エクスビバイト) をアドレス指定できますが、実際にはメモリの量は CPU、メモリ コントローラ、またはプリント回路基板の設計 (物理メモリ コネクタの数やはんだ付けされたメモリの量など) によって制限されます。
プログラム内蔵型コンピュータの各メモリロケーションには、何らかの2進数または10進数 が保持されます。そのデータが何らかのデータ型のデータとして解釈されるか、命令として解釈されるか、そしてその使用方法は、それを取り出して操作する 命令によって決定されます。
初期のプログラマの中には、メモリが高価だった時代に、命令とデータをワード単位で組み合わせてメモリを節約する手法を採用した者もいた。Manchester Mark 1は 40 ビットワード内に小さなデータを格納するための空間を持っていた (プロセッサはワードの途中の小さなセクションを無視した)。この空間はしばしば追加データストレージとして利用された。ウイルスなどの自己複製プログラムは、自身をデータとして扱うこともあれば、命令として扱うこともある。自己書き換えコードは、数バイトの節約に比べてテストと保守が不釣り合いに困難になり、またコンパイラやプロセッサがマシンの状態について想定する内容によって誤った結果が生じることもあるため、現在では一般的に非推奨となっている。しかし、それでもなお、細心の注意を払って意図的に使用されることがある。
現代のマルチタスク環境では、アプリケーションプロセスは通常、アドレス空間 (または空間群) に次のタイプのメモリ チャンクを持ちます。
アドレス空間の一部はまったくマップされない場合があります。
一部のシステムでは、マシンコード、定数、データがそれぞれ異なる場所に配置され、アドレスサイズも異なる「分割」メモリアーキテクチャを採用しています。例えば、 PIC18マイクロコントローラは、フラッシュメモリ内のマシンコードと定数のアドレス指定に21ビットのプログラムカウンタを使用し、SRAM内のデータのアドレス指定に12ビットのアドレスレジスタを使用します。
コンピュータプログラムは明示的に与えられたアドレスにアクセスすることができる。低レベルプログラミングでは、これは通常絶対アドレス、あるいは特定のアドレスを指すこともあり、高級言語ではポインタ相対アドレスを使用することもできます。相対アドレスとは、ある場所(ベースアドレス)を基準として位置を指定するものですアドレッシングモード他にも多くの種類があります。
論理アドレスを物理メモリと仮想メモリにマッピングすると、間接レベルの数も追加されます。以下を参照してください。
多くのプログラマーは、コード空間とデータ空間 (上記参照)、および物理メモリと仮想メモリ (上記参照) を区別しないようにメモリをアドレス指定することを好みます。つまり、数値的に同一のポインターは、RAM のまったく同じバイトを参照します。
しかし、初期のコンピュータの多くは、このようなフラットなメモリモデルをサポートしていませんでした。特にハーバード・アーキテクチャのマシンでは、プログラムストレージとデータストレージを完全に分離する必要がありました。多くの最新のDSP ( Motorola 56000など)は、プログラムストレージ、係数ストレージ、データストレージという3つの独立したストレージ領域を備えています。一般的に使用される命令の中には、これら3つの領域すべてから同時にフェッチするものがあり、ストレージ領域が少ないほど(たとえストレージの総バイト数が同じであっても)、それらの命令の実行速度は低下します。
初期の x86 プロセッサは、メモリ セグメントとそのセグメント内の オフセットという 2 つの数値の組み合わせに基づいて、セグメント化されたメモリ モデルアドレスを使用します。
一部のセグメントは、暗黙的にコードセグメント、命令専用セグメント、スタックセグメント、または通常のデータセグメントとして扱われます。用途は異なりますが、セグメントごとにメモリ保護が異なるわけではありません。フラットメモリモデルでは、すべてのセグメント(セグメントレジスタ)は通常ゼロに設定され、オフセットのみが可変です。
360/65と360/67において、IBMはプレフィックスという概念を導入した。[ 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までの後継機種では、変換をオンにして動作している場合、アドレスにはセグメント番号、ページ番号、オフセットが含まれます。初期モデルは2KiBと4KiBの両方のページサイズをサポートしていましたが、後期モデルは4KiBのみをサポートしました。IBMは後に、プライマリアドレス空間とセカンダリアドレス空間間でデータを移動するための命令を追加しました。
S/370-XAでは 31 ビットのアドレスが追加されましたが、4 KiB ページのセグメント/ページ/オフセット階層は保持されました。
ESA/370では、16 個のアクセス レジスタ (AR) と AR アクセス制御モードが追加されました。このモードでは、選択された AR によって指定されたアドレス空間を使用して 31 ビットのアドレスが変換されます。
z/Architecture は、マルチレベル ページ テーブルを備えた 64 ビットの仮想アドレス、実アドレス、絶対アドレスをサポートします。
再配置手順は、ストレージの最初の4,096バイトに適用されます。この領域にはすべての永続ストレージ割り当てが含まれており、一般的に監視プログラムにとって特別な意味を持ちます。再配置は、各アドレスに12ビットのプレフィックスを挿入することで実現されます。このプレフィックスの上位12ビットは0に設定され、したがって0~4095のアドレスに関連します。
プレフィックスにより、割り当てられた記憶域を含む実アドレスのブロックを、各CPUの絶対記憶域内の異なるブロックに割り当てることができるため、特に割り込み処理において、主記憶域を共有する複数のCPUが最小限の干渉で同時に動作できるようになります。