Paměťový model pro platformy x86 je způsob, jak specifikovat předpoklady, které musí kompilátor provést při generování kódu pro platformy s adresováním segmentované paměti nebo stránkovanou pamětí . Nejčastěji se tento termín používá při práci s různými staršími režimy platformy x86 .
Například existuje šest paměťových modelů na 16bitové x86 - kompatibilní platformě. Určují, jaké jsou předpoklady o výchozím segmentu registru a velikosti ukazatele.
16bitová architektura x86 díky přítomnosti čtyř segmentových registrů umožňuje současný přístup ke čtyřem paměťovým segmentům. Účel segmentových registrů:
Na takové platformě je obvyklé psát logickou adresu jako segment : offset , kde segment a offset jsou uvedeny v hexadecimálním zápisu .
V reálném režimu se pro výpočet fyzické adresy bajtu paměti posune hodnota odpovídajícího segmentového registru doleva o 4 bity a poté se přidá offset.
Například logická adresa 7522:F139 poskytuje 20bitovou fyzickou adresu:
75220 + F139 = 84359Je třeba poznamenat, že tento proces vede k aliasingu paměti , to znamená, že jakákoli daná fyzická adresa může mít více logických reprezentací. To ztěžuje srovnání ukazatelů.
V chráněném režimu se GDT a LDT používají ke stejnému účelu .
Ukazatele mohou být typu blízko (blízko), daleko (daleko) nebo obrovské (velké).
Blízký ukazatel odkazuje na aktuální segment, takže ani DS ani CS by se neměly změnit, když je ukazatel dereferencován. Ukazatele tohoto typu jsou nejrychlejší, ale jsou omezeny na oblast ukazatele 64 kilobajtů paměti (tj. aktuální segment).
Vzdálené ukazatele obsahují novou hodnotu DS nebo CS. Pro jejich použití je nutné změnit registr, dereferencovat paměť a poté registr obnovit. Takové ukazatele mohou ukazovat na 1 megabajt paměti. Je třeba poznamenat, že aritmetické operace s ukazateli (sčítání a odčítání) nemění úsek segmentu ukazatele, ale ovlivňují pouze jeho offset. Operace mimo nulu nebo 65535 (0xFFFF) budou podrobeny operaci modulo 64K, stejně jako jakákoli normální 16bitová operace. Například se znaménkem −1 se stane bez znaménka 0xFFFF nebo 65535.
Například následující kód přejde mimo rozsah a přepíše se:
char far * myfarptr = ( char far * ) 0x50000000L ; nepodepsané dlouhé počítadlo ; for ( čítač = 0 ; čítač < 128 * 1024 ; čítač ++ ) // přístup k paměti 128K * ( myfarptr + čítač ) = 7 ; // zapiš do něj všechny sedmičkyV určitém okamžiku se čítač bude rovnat (0x10000) a výsledná absolutní adresa překročí 0x5000:0000.
Obrovské ukazatele jsou v podstatě vzdálené ukazatele, ale jsou normalizovány pokaždé, když se změní, takže mají nejvyšší segment, který mohou oslovit. To je poměrně pomalé, ale umožňuje to ukazateli ukazovat na více segmentů a také umožňuje přesnější porovnání ukazatelů, jako by platforma byla plochým paměťovým modelem : toto deaktivuje aliasing paměti, jak je uvedeno výše, takže dva velké ukazatele ukazování na jednu a tutéž část paměti bude vždy stejné.
Paměťové modely jsou:
Modelka | Data | Kód |
Drobný* | u | |
Malý | zavřít** | u |
Střední | u | daleko |
Kompaktní | daleko | u |
velký | daleko | daleko |
Obrovský | obrovský | obrovský |
* V modelu Tiny všechny čtyři segmentové registry ukazují na stejný segment.
** U všech modelů s blízkými ukazateli na data se SS rovná DS .
V chráněném režimu nelze segment přepsat , přečíst ani spustit .
Proto při implementaci modelů paměti Small a Tiny musí registr segmentu kódu ukazovat na stejnou fyzickou adresu a mít stejné omezení jako registr segmentu dat. To eliminuje jednu z funkcí procesoru 80286 , který zajišťuje, že datové segmenty nebudou nikdy spuštěny a segmenty kódu nebudou nikdy přepsány (což znamená, že samočinné úpravy kódu jsou zcela zakázány ). Na procesorech 80386 s modelem ploché paměti je však možné chránit jednotlivé stránky paměti proti zápisu.
Paměťové modely nejsou omezeny na 16bitové programy. Segmentaci je možné použít i ve 32bitovém chráněném režimu (výsledkem jsou 48bitové ukazatele) a existují kompilátory C , které to podporují.
Segmentace v 32bitovém režimu však neumožňuje přístup k většímu adresnímu prostoru, než který pokrývá jeden segment, s výjimkou některých segmentů, které nejsou vždy zastoupeny v paměti, a lineární adresový prostor se jednoduše používá jako mezipaměť kvůli zvýšenému segmentovaný virtuální prostor.
Z velké části to umožňuje lepší ochranu přístupu k různým objektům (oblasti o velikosti až 1 megabajt mohou těžit z dělení ochrany přístupu po bajtech, na rozdíl od poněkud „hrubého“ 4 kB rozdělení, které nabízí jediný stránka), a proto se používá pouze ve speciálních aplikacích, jako je telekomunikační software.
Technicky vzato je „plochý“ 32bitový adresní prostor „malý“ paměťový model pro segmentovaný adresní prostor. Pod vlivem obou faktorů obsahují všechny čtyři segmentové registry stejnou hodnotu.
Na platformě x86-64 existuje sedm paměťových modelů [1] , přičemž většina symbolických odkazů je pouze 32bitových a pokud je adresa známa v době spojení (na rozdíl od kódu nezávislého na pozici ). To nemá vliv na použití ukazatelů, které jsou vždy plochými 64bitovými ukazateli, ale pouze z hlediska přístupu k hodnotám prostřednictvím alokace znaků.