Kısa cevap: Kullanılabilir adreslerin sayısı bunlardan daha azına eşittir:
- Bayt cinsinden bellek boyutu
- CPU'nun makine kelimesinde kaydedilebilen en büyük işaretsiz tam sayı
Uzun cevap ve yukarıdakilerin açıklaması:
Bellek baytlardan (B) oluşur. Her bayt 8 bit (b) 'den oluşur.
1 B = 8 b
1 GB RAM aslında 1 GiB'dir (gibabayt değil, gibibit). Fark şu:
1 GB = 10^9 B = 1 000 000 000 B
1 GiB = 2^30 B = 1 073 741 824 B
CPU makine kelimesi ne kadar büyük olursa olsun, her bellek baytının kendi adresi vardır. Örneğin. Intel 8086 CPU 16-bit idi ve belleği baytlara hitap ediyordu, modern 32-bit ve 64-bit CPU'lar da. Birinci sınırın nedeni budur - bellek baytlarından daha fazla adresiniz olamaz.
Bellek adresi, CPU'nun aradığı belleğe ulaşmak için belleğin başından atlaması gereken sadece bayt sayısıdır.
- İlk bayta erişmek için 0 bayt atlaması gerekir, bu nedenle ilk baytın adresi 0'dır.
- İkinci bayta erişmek için 1 bayt atlaması gerekir, böylece adresi 1 olur.
- (vb.)
- Son bayta erişmek için CPU 1073741823 baytı atlar, böylece adresi 1073741823 olur.
Şimdi 32-bit'in ne anlama geldiğini bilmek zorundasınız. Daha önce de belirttiğim gibi, bir makine kelimesinin boyutu.
Makine kelimesi CPU'nun sayıları tutmak için kullandığı bellek miktarıdır (RAM, önbellek veya dahili kayıtlarda). 32 bit CPU, sayıları tutmak için 32 bit (4 bayt) kullanır. Bellek adresleri de sayıdır, bu nedenle 32 bit CPU'da bellek adresi 32 bittir.
Şimdi şunu düşünün: Bir bitiniz varsa, üzerine iki değer kaydedebilirsiniz: 0 veya 1. Bir bit daha ekleyin ve dört değeriniz var: 0, 1, 2, 3. Üç bitte sekiz değer kaydedebilirsiniz : 0, 1, 2 ... 6, 7. Bu aslında bir ikili sistemdir ve şöyle çalisir:
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
Tam olarak her zamanki toplama gibi çalışır, ancak maksimum rakam 9 değil 9'dur. Ondalık 0 0000
, daha sonra 1 ekler ve alırsınız 0001
, bir kez daha eklersiniz 0010
. Burada olan, ondalık sayıya sahip olmak 09
ve bir tane eklemek gibidir: 9'dan 0'a değiştirir ve sonraki basamağı artırırsınız.
Yukarıdaki örnekte, her zaman sabit sayıda bit içeren bir sayıda tutabileceğiniz maksimum bir değer olduğunu görebilirsiniz - çünkü tüm bitler 1 olduğunda ve değeri 1 artırmaya çalıştığınızda, tüm bitler 0 olur ve böylece numara. Buna tamsayı taşması denir ve hem kullanıcılar hem de geliştiriciler için birçok hoş olmayan soruna neden olur.
11111111 = 255
+ 1
-----------
100000000 = 0 (9 bits here, so 1 is trimmed)
- 1 bit için en büyük değer 1'dir,
- 2 bit - 3,
- 3 bit - 7,
- 4 bit - 15
Mümkün olan en büyük sayı her zaman 2 ^ N-1'dir, burada N bit sayısıdır. Daha önce söylediğim gibi, bir bellek adresi bir sayıdır ve aynı zamanda bir maksimum değere sahiptir. Bu yüzden makine kelimesinin boyutu da kullanılabilir bellek adreslerinin sayısı için bir sınırdır - bazen CPU'nuz daha fazla belleği ele alacak kadar büyük sayıları işleyemez.
32 bitte 0 ila 2 ^ 32-1 arasındaki sayıları tutabilirsiniz ve bu 4 294 967 295'dir. 1 GB RAM'deki en büyük adresten daha fazladır, bu nedenle özel durum miktarınızda RAM sınırlayıcı faktör olacaktır.
32 bit CPU için RAM sınırı teorik olarak 4 GB'dir (2 ^ 32) ve 64 bit CPU için 16 EB'dir (exabytes, 1 EB = 2 ^ 30 GB). Başka bir deyişle, 64-bit CPU tüm İnternet'e 200 kere hitap edebilir;) ( WolframAlpha tarafından tahmin edilmektedir ).
Ancak, gerçek hayattaki işletim sistemlerinde 32 bit CPU'lar yaklaşık 3 GiB RAM'e hitap edebilir. Bunun nedeni işletim sisteminin iç mimarisi - bazı adresler başka amaçlar için ayrılmıştır. Wikipedia'da bu sözde 3 GB engel hakkında daha fazla bilgi edinebilirsiniz . Bu sınırı Fiziksel Adres Uzantısı ile kaldırabilirsiniz .
Bellek adreslemesinden bahsetmem gereken birkaç şey var: sanal bellek , segmentasyon ve sayfalama .
Sanal bellek
@Daniel R Hicks'in başka bir cevapta belirttiği gibi, işletim sistemleri sanal bellek kullanıyor. Bunun anlamı, uygulamaların gerçek bellek adresleri üzerinde çalışmadığı, ancak OS tarafından sağlanan adresler üzerinde çalıştığıdır.
Bu teknik, işletim sisteminin bazı verileri RAM'den Pagefile (Windows) veya Swap (* NIX) olarak adlandırmasına izin verir. HDD, RAM'den daha az büyüklüktedir, ancak nadiren erişilen veriler için ciddi bir sorun değildir ve işletim sisteminin uygulamalara gerçekte kurduğunuzdan daha fazla RAM sağlamasına izin verir.
Çağrı
Şimdiye kadar bahsettiğimiz konuya düz adresleme şeması deniyor.
Sayfalama, düz modeldeki bir makine sözcüğü ile normalde yapabileceğiniz daha fazla belleği ele alan alternatif bir adresleme şemasıdır.
4 harfli kelimelerle dolu bir kitap düşünün. Her sayfada 1024 sayı olduğunu varsayalım. Bir numaraya hitap etmek için iki şey bilmeniz gerekir:
- Sözcüğün yazdırıldığı sayfa sayısı.
- Bu sayfadaki hangi kelime aradığınız kelime.
İşte şimdi modern x86 işlemcilerin belleği nasıl işlediği. 4 KiB sayfasına (her biri 1024 makine kelimesi) ayrılmıştır ve bu sayfaların sayıları vardır. (aslında sayfaları da 4 MiB büyük ya 2 MiB olabilir PAE ). Bellek hücresini adreslemek istediğinizde, o sayfadaki sayfa numarasına ve adrese ihtiyacınız vardır. Her bellek hücresine tam olarak bir çift sayı tarafından başvurulduğunu unutmayın; bu bölümleme için geçerli olmayacaktır.
segmantasyon
Bu, sayfalamaya oldukça benziyor. Intel 8086'da sadece bir örnek vermek için kullanıldı. Adres gruplarına artık sayfalar değil, bellek segmentleri deniyor. Fark, segmentlerin üst üste gelebilmesidir ve çok fazla örtüşmektedirler. Örneğin, 8086'da 4096 farklı segmentten çoğu bellek hücresi mevcuttu.
Bir örnek:
Diyelim ki 8 bayt belleğimiz var, 4. bayt hariç tümü 256 tane olan sıfırlar var.
Düz bellek modeli için örnek:
_____
| 0 |
| 0 |
| 0 |
| 255 |
| 0 |
| 0 |
| 0 |
| 0 |
-----
4 bayt sayfalar içeren disk belleği için örnek :
PAGE0
_____
| 0 |
| 0 |
| 0 | PAGE1
| 255 | _____
----- | 0 |
| 0 |
| 0 |
| 0 |
-----
1 baytlık kaydırılmış 4 baytlık segmentlere sahip bölümlenmiş bellek için örnek :
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 |
----- ----- ----- -----
Gördüğünüz gibi 4. bayt dört şekilde adreslenebilir: (0'dan adresleme)
- Segment 0, ofset 3
- Segment 1, ofset 2
- Segment 2, ofset 1
- Segment 3, ofset 0
Her zaman aynı bellek hücresidir.
Gerçek hayattaki uygulamalarda segmentler 1 bayttan fazla kaydırılır (8086 için 16 bayt).
Segmentasyon ile ilgili kötü olan şey karmaşık olmasıdır (ancak bence bunu zaten biliyorsunuz;) İyi olan, modüler programlar oluşturmak için bazı akıllı teknikler kullanabilmenizdir.
Örneğin, bir parçayı bir parçaya yükleyebilir, sonra parçanın gerçekte olduğundan daha küçük olduğunu (modülü tutacak kadar küçük), ardından sözde daha küçük olanla örtüşmeyen ilk parçayı seçip sonraki modülü yükleyebilirsiniz , ve bunun gibi. Temel olarak bu şekilde aldığınız şey, değişken boyutlu sayfalardır.