簡単な答え:使用可能なアドレスの数は、これらのうち小さい方に等しくなります。
- バイト単位のメモリサイズ
- CPUのマシンワードに保存できる最大の符号なし整数
上記の長い答えと説明:
メモリはバイト(B)で構成されます。各バイトは8ビット(b)で構成されます。
1 B = 8 b
1 GBのRAMは、実際には1 GiB(ギガバイトではなくギガバイト)です。違いは:
1 GB = 10^9 B = 1 000 000 000 B
1 GiB = 2^30 B = 1 073 741 824 B
CPUのマシンワードがどれほど大きくても、メモリの各バイトには独自のアドレスがあります。例えば。Intel 8086 CPUは16ビットであり、バイト単位でメモリをアドレス指定していたため、最新の32ビットおよび64ビットCPUも同様です。これが最初の制限の原因です-メモリバイトより多くのアドレスを持つことはできません。
メモリアドレスは、CPUがメモリの先頭からスキップして、探しているものに到達する必要があるバイト数です。
- 最初のバイトにアクセスするには、0バイトをスキップする必要があるため、最初のバイトのアドレスは0です。
- 2番目のバイトにアクセスするには、1バイトをスキップする必要があるため、アドレスは1です。
- (など...)
- 最後のバイトにアクセスするために、CPUは1073741823バイトをスキップするため、そのアドレスは1073741823です。
次に、32ビットが実際に何を意味するかを知る必要があります。前に述べたように、それは機械語のサイズです。
マシンワードは、CPUが数値を保持するために使用するメモリの量です(RAM、キャッシュ、または内部レジスター内)。32ビットCPUは、32ビット(4バイト)を使用して数値を保持します。メモリアドレスも数値であるため、32ビットCPUではメモリアドレスは32ビットで構成されます。
これについて考えてみましょう:1ビットの場合、2つの値を保存できます:0または1。もう1ビットを追加し、4つの値を持っています:0、1、2、3。3ビットで、8つの値を保存できます:0、1、2 ... 6、7.これは実際にはバイナリシステムであり、次のように機能します。
Decimal Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
通常の加算とまったく同じように機能しますが、最大桁は9ではなく1です。10進数の0は0000
、1を追加してgetし0001
、もう一度1を追加するとが得られます0010
。ここで起こったことは、10進数を09
持ち、1を追加したようなものです。9を0に変更し、次の桁をインクリメントします。
上記の例から、常に一定のビット数の数値を保持できる最大値があることがわかります-すべてのビットが1で、値を1増加させようとすると、すべてのビットが0になるため、数。これは整数オーバーフローと呼ばれ、ユーザーと開発者の両方にとって多くの不快な問題を引き起こします。
11111111 = 255
+ 1
-----------
100000000 = 0 (9 bits here, so 1 is trimmed)
- 1ビットの最大値は1です
- 2ビット-3
- 3ビット-7
- 4ビット-15
可能な最大数は常に2 ^ N-1です。Nはビット数です。前にも言ったように、メモリアドレスは数値であり、最大値もあります。そのため、マシンワードのサイズは使用可能なメモリアドレスの数の制限でもあります。CPUが、より多くのメモリをアドレスするのに十分な大きさの数値を処理できない場合があります。
したがって、32ビットでは、0から2 ^ 32-1までの数値を保持できます。これは4 294 967 295です。1GB RAMの最大アドレスを超えるため、特定のケースではRAMの量が制限要因になります。
32ビットCPUのRAM制限は理論的には4 GB(2 ^ 32)であり、64ビットCPUの場合は16 EB(エクサバイト、1 EB = 2 ^ 30 GB)です。言い換えれば、64ビットCPUはインターネット全体に対処できます... 200回;)(WolframAlphaによる推定)
ただし、実際のオペレーティングシステムでは、32ビットCPUは約3 GiBのRAMに対応できます。これは、オペレーティングシステムの内部アーキテクチャのためです-一部のアドレスは他の目的のために予約されています。このいわゆる3 GBの障壁については、ウィキペディアで詳しく読むことができます。この制限は、Physical Address Extensionで解除できます。
メモリのアドレス指定について言えば、言及すべきことはほとんどありません。仮想メモリ、セグメンテーション、およびページングです。
仮想メモリ
@Daniel R Hicksが別の答えで指摘したように、OSは仮想メモリを使用します。つまり、アプリケーションは実際には実際のメモリアドレスではなく、OSが提供するアドレスで動作します。
この手法により、オペレーティングシステムはRAMからいわゆるページファイル(Windows)またはスワップ(* NIX)にデータを移動できます。HDDはRAMよりも数倍遅いですが、めったにアクセスされないデータにとっては重大な問題ではなく、OSは実際にインストールしたよりも多くのRAMをアプリケーションに提供できます。
ページング
これまで話してきたことは、フラットアドレッシングスキームと呼ばれます。
ページングは、フラットモデルの1つのマシンワードで通常可能だったより多くのメモリをアドレス指定できる代替のアドレス指定方式です。
4文字の単語で満たされた本を想像してください。各ページに1024個の数字があるとしましょう。番号に対応するには、次の2つのことを知る必要があります。
- その単語が印刷されるページの数。
- そのページのどの単語があなたが探しているものです。
これがまさに最新のx86 CPUがメモリを処理する方法です。4つのKiBページ(それぞれ1024マシンワード)に分割され、それらのページには番号があります。(実際には、ページは4 MiBの大きさまたは2 MiBでPAEを使用できます)。メモリセルのアドレスを指定するには、そのページのページ番号とアドレスが必要です。各メモリセルは正確に1組の数字で参照されますが、セグメンテーションの場合はそうではないことに注意してください。
セグメンテーション
まあ、これはページングに非常に似ています。1つの例を挙げるために、Intel 8086で使用されました。アドレスのグループは、ページではなくメモリセグメントと呼ばれるようになりました。違いは、セグメントがオーバーラップできることであり、セグメントは多くオーバーラップします。たとえば、8086では、ほとんどのメモリセルは4096の異なるセグメントから利用できました。
例:
8バイトのメモリがあり、255に等しい4番目のバイトを除いてすべてゼロを保持するとします。
フラットメモリモデルの図:
_____
| 0 |
| 0 |
| 0 |
| 255 |
| 0 |
| 0 |
| 0 |
| 0 |
-----
4バイトページのページメモリの図:
PAGE0
_____
| 0 |
| 0 |
| 0 | PAGE1
| 255 | _____
----- | 0 |
| 0 |
| 0 |
| 0 |
-----
4バイトセグメントが1シフトされたセグメントメモリの図
SEG 0
_____ SEG 1
| 0 | _____ SEG 2
| 0 | | 0 | _____ SEG 3
| 0 | | 0 | | 0 | _____ SEG 4
| 255 | | 255 | | 255 | | 255 | _____ SEG 5
----- | 0 | | 0 | | 0 | | 0 | _____ SEG 6
----- | 0 | | 0 | | 0 | | 0 | _____ SEG 7
----- | 0 | | 0 | | 0 | | 0 | _____
----- | 0 | | 0 | | 0 | | 0 |
----- ----- ----- -----
ご覧のとおり、4番目のバイトは4つの方法でアドレス指定できます:(0からアドレス指定)
- セグメント0、オフセット3
- セグメント1、オフセット2
- セグメント2、オフセット1
- セグメント3、オフセット0
常に同じメモリセルです。
実際の実装では、セグメントは1バイト以上シフトされます(8086では16バイトでした)。
セグメンテーションの悪い点は複雑だということです(しかし、あなたはすでにそれを知っていると思います;)良いことは、いくつかの巧妙なテクニックを使ってモジュール式プログラムを作成できることです。
たとえば、いくつかのモジュールをセグメントにロードし、セグメントが実際よりも小さいふりをして(モジュールを保持するのに十分なだけ小さい)、次にその疑似小さいセグメントと重ならない最初のセグメントを選択し、次のモジュールをロードできます、 等々。基本的にこの方法で得られるのは、可変サイズのページです。