Minnesmodell Intel x86

Minnesmodellen för x86-plattformar  är ett sätt att specificera de antaganden som kompilatorn måste göra vid generering av kod för plattformar med segmenterad minnesadressering eller pagat minne . Oftast används termen när man arbetar med olika äldre lägen på x86 -plattformen .

Till exempel finns det sex minnesmodeller på en 16-bitars x86 - kompatibel plattform. De bestämmer vilka antaganden som görs om standardregistersegmentet och pekarstorleken .

Minnessegmentering

16-bitars x86 - arkitekturen, på grund av närvaron av fyra segmentregister, tillåter samtidig åtkomst till fyra minnessegment. Syfte med segmentregister:

På en sådan plattform är det vanligt att skriva en logisk adress som segment : offset , där segmentet och offset anges i hexadecimal notation .

I verkligt läge, för att beräkna den fysiska adressen för en minnesbyte, skiftas värdet på motsvarande segmentregister åt vänster med 4 bitar, och sedan läggs förskjutningen till.

Till exempel ger den logiska adressen 7522:F139 en 20-bitars fysisk adress:

75220 + F139 = 84359

Det bör noteras att denna process resulterar i minnesaliasing , det vill säga att varje given fysisk adress kan ha flera logiska representationer. Detta gör jämförelsen av pekare svårare.

I skyddat läge används GDT och LDT för samma ändamål .

Pekarmått

Pekare kan vara av typen nära (nära), långt (långt) eller enorma (stora).

Närpekaren hänvisar till det aktuella segmentet, så varken DS eller CS bör ändras när pekaren avreferens. Pekare av denna typ är de snabbaste, men är begränsade till ett pekarea på 64 kilobyte minne (det vill säga det aktuella segmentet).

Fjärrpekare innehåller det nya DS- eller CS-värdet. För att använda dem måste registret ändras, minnet avreferenseras och sedan måste registret återställas. Sådana pekare kan peka på 1 megabyte minne. Det bör noteras att aritmetiska operationer med pekare (addition och subtraktion) inte ändrar sektionen av pekarsegmentet, utan bara påverkar dess offset. Operationer utanför noll eller 65535 (0xFFFF) kommer att utsättas för en modulo 64K operation, precis som alla vanliga 16-bitars operationer. Till exempel, signerad −1 blir osignerad 0xFFFF eller 65535.

Till exempel kommer följande kod att gå utanför räckvidden och skriva över sig själv:

char far * myfarptr = ( char far * ) 0x50000000L ; osignerad lång räknare ; for ( räknare = 0 ; räknare < 128 * 1024 ; räknare ++ ) // åtkomst till 128K minne * ( myfarptr + räknare ) = 7 ; // skriv alla sjuor i den

Vid någon tidpunkt kommer räknaren att bli lika med (0x10000), och den resulterande absoluta adressen kommer att överstiga 0x5000:0000.

Enorma pekare är i huvudsak långt pekare, men normaliseras varje gång de ändras så att de har det högsta segmentet de kan adressera. Detta är ganska långsamt, men det tillåter en pekare att peka på flera segment, och det möjliggör också mer exakt jämförelse av pekare, som om plattformen vore en platt minnesmodell : detta inaktiverar minnesaliasing som nämnts ovan, så två stora pekare att peka på ett och samma minne kommer alltid att vara lika.

Minnesmodeller

Minnesmodeller är:

Modell Data Koden
Mycket liten* nära
Små stänga** nära
Medium nära långt
Kompakt långt nära
Stor långt långt
Enorm enorm enorm

* I Tiny-modellen pekar alla fyra segmentregistren mot samma segment.

** I alla modeller med nära-pekare till data är SS lika med DS .

Andra plattformar

I skyddat läge kan segmentet inte skrivas över, läsas eller köras.

Vid implementering av små och små minnesmodeller måste därför kodsegmentregistret peka på samma fysiska adress och ha samma begränsning som datasegmentregistret. Detta eliminerar en av funktionerna i 80286-processorn , som säkerställer att datasegment aldrig exekveras och kodsegment aldrig skrivs över (vilket innebär att självmodifierande kod är helt förbjuden ). På 80386-processorer med sin platta minnesmodell är det dock möjligt att skrivskydda enskilda minnessidor.

Minnesmodeller är inte begränsade till 16-bitarsprogram. Det är möjligt att använda segmentering i 32-bitars skyddat läge också (vilket resulterar i 48-bitars pekare), och det finns C-kompilatorer som stöder det.

Segmentering i 32-bitarsläge tillåter dock inte åtkomst till mer adressutrymme än det som täcker ett segment, förutom vissa segment som inte alltid representeras i minnet, och det linjära adressutrymmet används helt enkelt som en cache på grund av den ökade segmenterat virtuellt utrymme.

För det mesta möjliggör detta bättre skydd av åtkomst till olika objekt (områden upp till 1 megabyte i storlek kan dra nytta av byte-för-byte-delning av åtkomstskydd, i motsats till den ganska "grova" 4 KiB-delningen som erbjuds av en enda sida), och används därför endast i speciella applikationer såsom telekommunikationsprogramvara.

Tekniskt sett är ett "platt" 32-bitars adressutrymme en "liten" minnesmodell för ett segmenterat adressutrymme. Under inverkan av båda faktorerna innehåller alla fyra segmentregistren samma värde.

x86-64- plattformen finns det sju minnesmodeller [1] , där de flesta symboliska länkar endast är 32-bitars, och om adressen är känd vid länktid (i motsats till positionsoberoende kod ). Detta påverkar inte användningen av pekare, som alltid är platta 64-bitars pekare, utan endast vad gäller värdeåtkomst via teckenallokering.

Se även

Anteckningar

  1. アーカイブされたコピー. Hämtad 26 september 2010. Arkiverad från originalet 16 juli 2011.

Litteratur

  • Turbo C++ Version 3.0 Användarhandbok . Borland International, 1992.