Model pamięci Intel - Intel Memory Model

W informatyce , Intel Pamięć modelu odnosi się do zestawu sześciu różnych modeli pamięci na x86 obsługi procesora w trybie rzeczywistym , które określają sposób segmentu rejestry są używane i wielkości domyślnej wskaźników.

Segmentacja pamięci

Cztery rejestry są używane w odniesieniu do czterech segmentów w 16-bitowej segmentowej architekturze pamięci x86. DS ( segment danych ), CS ( segment kodu ), SS ( segment stosu ) i ES (dodatkowy segment). Inny 16-bitowy rejestr może działać jako przesunięcie w danym segmencie, więc adres logiczny na tej platformie jest zapisywany jako segment : offset , zwykle w notacji szesnastkowej . W trybie rzeczywistym, aby obliczyć adres fizyczny bajtu pamięci, sprzęt przesuwa zawartość odpowiedniego rejestru segmentowego o 4 bity w lewo (skutecznie mnożąc przez 16), a następnie dodaje przesunięcie.

Na przykład adres logiczny 7522: F139 daje 20-bitowy adres fizyczny:

  75220
+ F139
  84359

Należy zauważyć, że proces ten prowadzi do aliasingu pamięci, tak że każdy podany adres fizyczny ma do 4096 odpowiadających sobie adresów logicznych. To komplikuje porównanie wskaźników do różnych segmentów.

Rozmiary wskaźników

Formaty wskaźników są znane jako bliskie , dalekie lub ogromne .

  • Wskaźniki bliskie to 16-bitowe przesunięcia w segmencie odniesienia, tj. DS dla danych i CS dla kodu. Są to najszybsze wskaźniki, ale są ograniczone do 64 KB pamięci (do skojarzonego segmentu typu danych). Wskaźniki bliskie mogą być przechowywane w rejestrach (zwykle SI i DI).
    mov bx, word [reg]
    mov ax, word [bx]
    mov dx, word [bx+2]
  • Odległe wskaźniki to 32-bitowe wskaźniki zawierające segment i przesunięcie. Aby z nich skorzystać, należy użyć rejestru segmentowego ES za pomocą instrukcji les [reg]|[mem],dword [mem]|[reg] . Mogą odnosić się do 1024  KB pamięci. Zwróć uwagę, że arytmetyka wskaźnika (dodawanie i odejmowanie) nie modyfikuje segmentu wskaźnika, a jedynie jego przesunięcie. Operacje, które przekraczają granice zera lub 65535 (0xFFFF), zostaną poddane operacji modulo 64K, tak jak każda normalna operacja 16-bitowa. Na przykład, jeśli rejestr segmentu jest ustawiony na 0x5000, a przesunięcie jest zwiększane, w momencie, gdy to przesunięcie licznika osiągnie wartość (0x10000), wynikowy adres bezwzględny zmieni się na 0x5000: 0000.
    les bx,dword [reg]
    mov ax,word [es:bx]
    mov dx,word [es:bx+2]
  • Ogromne wskaźniki są zasadniczo dalekimi wskaźnikami, ale są (w większości) normalizowane za każdym razem, gdy są modyfikowane, tak aby miały najwyższy możliwy segment dla tego adresu. Jest to bardzo powolne, ale pozwala wskaźnikowi wskazywać wiele segmentów i pozwala na dokładne porównania wskaźników, tak jakby platforma była płaskim modelem pamięci : zabrania aliasingu pamięci, jak opisano powyżej, więc dwa ogromne wskaźniki odnoszące się do tej samej pamięci lokalizacja są zawsze równe.
    les bx,dword [reg]
    mov ax,word [es:bx]
    add bx,2
    test bx,0xfff0
    jz lbl
    sub bx,0x10
    mov dx,es
    inc dx
    mov es,dx
 lbl:
    mov dx,word [es:bx]

Modele pamięci

Modele pamięci to:

Model Dane Kod Definicja
Malutki* Blisko CS = DS = SS
Mały Blisko** Blisko DS = SS
Średni Blisko** daleko DS = SS, wiele segmentów kodu
Kompaktowy daleko Blisko pojedynczy segment kodu, wiele segmentów danych
Duży daleko daleko wiele segmentów kodu i danych
Olbrzymi olbrzymi daleko wiele segmentów kodu i danych; pojedyncza tablica może mieć> 64 KB

Inne platformy

W trybie chronionym segment nie może być jednocześnie zapisywalny i wykonywalny. Dlatego przy wdrażaniu modelu Tiny memory rejestr segmentu kodu musi wskazywać na ten sam adres fizyczny i mieć takie same ograniczenia jak rejestr segmentu danych. To pokonało jedną z funkcji 80286 , która zapewnia, że ​​segmenty danych nigdy nie będą wykonywalne, a segmenty kodu nigdy nie będą zapisywalne (co oznacza, że samomodyfikujący się kod nigdy nie jest dozwolony). Jednak w 80386, dzięki jednostce zarządzającej pamięcią stronicowaną , można zabezpieczyć poszczególne strony pamięci przed zapisem.

Modele pamięci nie są ograniczone do programów 16-bitowych. Możliwe jest również użycie segmentacji w 32-bitowym trybie chronionym (co daje 48-bitowe wskaźniki) i istnieją kompilatory języka C, które to obsługują. Jednak segmentacja w trybie 32-bitowym nie pozwala na dostęp do większej przestrzeni adresowej niż to, co obejmowałby pojedynczy segment, chyba że niektóre segmenty nie zawsze są obecne w pamięci, a liniowa przestrzeń adresowa jest używana tylko jako pamięć podręczna w większej segmentowanej przestrzeni wirtualnej . Zapewnia lepszą ochronę dostępu do różnych obiektów (obszary o długości do 1 MB mogą korzystać z jednobajtowej ziarnistości ochrony dostępu w porównaniu z grubą ziarnistością 4 KiB oferowaną przez pojedyncze stronicowanie) i dlatego jest używana tylko w wyspecjalizowanych zastosowaniach, takich jak telekomunikacja oprogramowanie. Technicznie rzecz biorąc, „płaska” 32-bitowa przestrzeń adresowa jest „małym” modelem pamięci dla segmentowanej przestrzeni adresowej. W obu czasach wszystkie cztery rejestry segmentowe zawierają jedną i tę samą wartość.

x86-64

Na platformie x86-64 istnieje w sumie siedem modeli pamięci, ponieważ większość odwołań do symboli ma szerokość tylko 32 bity, a adresy są znane w czasie łącza (w przeciwieństwie do kodu niezależnego od pozycji ). Nie ma to wpływu na używane wskaźniki, które zawsze są płaskimi wskaźnikami 64-bitowymi, ale tylko na sposób umieszczania wartości, do których należy uzyskać dostęp za pomocą symboli.

Zobacz też

Bibliografia

  • Podręcznik użytkownika Turbo C ++ wersja 3.0 . Borland International, Copyright 1992.

Bibliografia