Jawaban singkat: Jumlah alamat yang tersedia sama dengan yang lebih kecil dari itu:
- Ukuran memori dalam byte
- Integer unsigned terbaik yang dapat disimpan dalam kata mesin CPU
Jawaban panjang dan penjelasan di atas:
Memori terdiri dari byte (B). Setiap byte terdiri dari 8 bit (b).
1 B = 8 b
RAM 1 GB sebenarnya adalah 1 GiB (gibibyte, bukan gigabyte). Perbedaannya adalah:
1 GB = 10^9 B = 1 000 000 000 B
1 GiB = 2^30 B = 1 073 741 824 B
Setiap byte memori memiliki alamatnya sendiri, tidak peduli seberapa besar kata mesin CPU. Misalnya. Intel 8086 CPU adalah 16-bit dan itu menangani memori dengan byte, begitu juga CPU 32-bit dan 64-bit modern. Itulah penyebab batas pertama - Anda tidak dapat memiliki lebih banyak alamat daripada memori byte.
Alamat memori hanya sejumlah byte yang harus dilewati CPU dari awal memori untuk sampai ke yang dicari.
- Untuk mengakses byte pertama, ia harus melewati 0 byte, jadi alamat byte pertama adalah 0.
- Untuk mengakses byte kedua, ia harus melewati 1 byte, jadi alamatnya adalah 1.
- (Dan seterusnya...)
- Untuk mengakses byte terakhir, CPU melompati 1073741823 byte, jadi alamatnya adalah 1073741823.
Sekarang Anda harus tahu apa arti sebenarnya 32-bit. Seperti yang saya sebutkan sebelumnya, itu ukuran kata mesin.
Kata mesin adalah jumlah memori yang digunakan CPU untuk menyimpan angka (dalam RAM, cache, atau register internal). CPU 32-bit menggunakan 32 bit (4 byte) untuk menyimpan angka. Alamat memori juga angka, jadi pada CPU 32-bit alamat memori terdiri dari 32 bit.
Sekarang pikirkan tentang ini: jika Anda memiliki satu bit, Anda dapat menyimpan dua nilai di atasnya: 0 atau 1. Tambahkan satu bit lagi dan Anda memiliki empat nilai: 0, 1, 2, 3. Pada tiga bit, Anda dapat menyimpan delapan nilai : 0, 1, 2 ... 6, 7. Ini sebenarnya adalah sistem biner dan berfungsi seperti itu:
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
Ini berfungsi persis seperti penambahan biasa, tetapi digit maksimum adalah 1, bukan 9. Desimal 0 adalah 0000
, lalu Anda tambahkan 1 dan dapatkan 0001
, tambahkan satu lagi dan yang Anda miliki 0010
. Seperti apa happend di sini dengan memiliki desimal 09
dan menambahkan satu: Anda mengubah 9 menjadi 0 dan menambah digit berikutnya.
Dari contoh di atas, Anda dapat melihat bahwa selalu ada nilai maksimum yang dapat disimpan dalam angka dengan jumlah bit konstan - karena ketika semua bit bernilai 1 dan Anda mencoba meningkatkan nilainya dengan 1, semua bit akan menjadi 0, sehingga memecahkan jumlah. Ini disebut integer overflow dan menyebabkan banyak masalah yang tidak menyenangkan, baik untuk pengguna maupun pengembang.
11111111 = 255
+ 1
-----------
100000000 = 0 (9 bits here, so 1 is trimmed)
- Untuk 1 bit, nilai terbesar adalah 1,
- 2 bit - 3,
- 3 bit - 7,
- 4 bit - 15
Angka terbesar yang mungkin adalah 2 ^ N-1, di mana N adalah jumlah bit. Seperti yang saya katakan sebelumnya, alamat memori adalah angka dan juga memiliki nilai maksimum. Itu sebabnya ukuran kata mesin juga merupakan batasan untuk jumlah alamat memori yang tersedia - terkadang CPU Anda tidak dapat memproses angka yang cukup besar untuk mengatasi lebih banyak memori.
Jadi pada 32 bit Anda dapat menyimpan angka dari 0 hingga 2 ^ 32-1, dan itu adalah 4 294 967 295. Ini lebih dari alamat terbesar dalam 1 GB RAM, jadi dalam kasus spesifik Anda jumlah RAM akan menjadi faktor pembatas.
Batas RAM untuk CPU 32-bit secara teoritis adalah 4 GB (2 ^ 32) dan untuk CPU 64-bit adalah 16 EB (exabytes, 1 EB = 2 ^ 30 GB). Dengan kata lain, CPU 64-bit dapat menangani seluruh Internet ... 200 kali;) (diperkirakan oleh WolframAlpha ).
Namun, dalam sistem operasi kehidupan nyata CPU 32-bit dapat mengatasi sekitar 3 GiB RAM. Itu karena arsitektur internal sistem operasi - beberapa alamat dicadangkan untuk keperluan lain. Anda dapat membaca lebih lanjut tentang penghalang 3 GB ini di Wikipedia . Anda dapat mengangkat batas ini dengan Ekstensi Alamat Fisik .
Berbicara tentang pengalamatan memori, ada beberapa hal yang harus saya sebutkan: memori virtual , segmentasi dan paging .
Memori virtual
Seperti @Daniel R Hicks tunjukkan dalam jawaban lain, OS menggunakan memori virtual. Maksudnya adalah bahwa aplikasi sebenarnya tidak beroperasi pada alamat memori nyata, tetapi yang disediakan oleh OS.
Teknik ini memungkinkan sistem operasi untuk memindahkan beberapa data dari RAM ke apa yang disebut Pagefile (Windows) atau Swap (* NIX). HDD beberapa magnitude lebih lambat dari RAM, tetapi itu bukan masalah serius untuk data yang jarang diakses dan memungkinkan OS untuk menyediakan aplikasi lebih banyak RAM daripada yang sebenarnya telah Anda instal.
Paging
Apa yang kami bicarakan sejauh ini disebut skema pengalamatan datar.
Paging adalah skema pengalamatan alternatif yang memungkinkan untuk mengatasi lebih banyak memori yang biasanya Anda dapat dengan satu kata mesin dalam model datar.
Bayangkan sebuah buku berisi kata-kata 4 huruf. Katakanlah ada 1024 angka di setiap halaman. Untuk mengatasi suatu nomor, Anda harus mengetahui dua hal:
- Jumlah halaman tempat kata itu dicetak.
- Kata mana pada halaman itu yang Anda cari.
Nah, itulah tepatnya bagaimana x86 CPU modern menangani memori. Ini dibagi menjadi 4 halaman KiB (masing-masing 1024 kata mesin) dan halaman-halaman itu memiliki angka. (sebenarnya halaman juga bisa berukuran 4 MiB besar atau 2 MiB dengan PAE ). Saat Anda ingin menangani sel memori, Anda memerlukan nomor halaman dan alamat di halaman itu. Perhatikan bahwa setiap sel memori direferensikan oleh tepat sepasang angka, itu tidak akan menjadi kasus untuk segmentasi.
Segmentasi
Nah, ini sangat mirip dengan paging. Itu digunakan di Intel 8086, hanya untuk menyebutkan satu contoh. Grup alamat sekarang disebut segmen memori, bukan halaman. Perbedaannya adalah segmen dapat tumpang tindih, dan mereka banyak tumpang tindih. Misalnya pada 8086 sebagian besar sel memori tersedia dari 4.096 segmen yang berbeda.
Sebuah contoh:
Katakanlah kita memiliki 8 byte memori, semua nol memegang kecuali 4 byte yang sama dengan 255.
Ilustrasi untuk model memori datar:
_____
| 0 |
| 0 |
| 0 |
| 255 |
| 0 |
| 0 |
| 0 |
| 0 |
-----
Ilustrasi untuk memori halaman dengan halaman 4-byte:
PAGE0
_____
| 0 |
| 0 |
| 0 | PAGE1
| 255 | _____
----- | 0 |
| 0 |
| 0 |
| 0 |
-----
Ilustrasi untuk memori tersegmentasi dengan segmen 4-byte digeser oleh 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 |
----- ----- ----- -----
Seperti yang Anda lihat, byte ke-4 dapat diatasi dengan empat cara: (mengatasi dari 0)
- Segmen 0, offset 3
- Segmen 1, offset 2
- Segmen 2, offset 1
- Segmen 3, offset 0
Itu selalu sel memori yang sama.
Dalam implementasi kehidupan nyata, segmen digeser lebih dari 1 byte (untuk 8086 itu 16 byte).
Apa yang buruk tentang segmentasi adalah rumit (tapi saya pikir Anda sudah tahu itu;) Yang bagus, adalah Anda bisa menggunakan beberapa teknik pintar untuk membuat program modular.
Misalnya Anda dapat memuat beberapa modul ke dalam segmen, kemudian berpura-pura segmen lebih kecil dari yang sebenarnya (hanya cukup kecil untuk menampung modul), lalu pilih segmen pertama yang tidak tumpang tindih dengan modul semu yang lebih kecil dan muat modul berikutnya , dan seterusnya. Pada dasarnya yang Anda dapatkan dengan cara ini adalah halaman dengan ukuran variabel.