Muistimalli Intel x86

Muistimalli x86 - alustoille  on tapa määrittää oletukset , jotka kääntäjän on tehtävä luodessaan koodia alustoille , joissa on segmentoitu muistiosoite tai sivuttu muisti . Useimmiten termiä käytetään työskenneltäessä x86 -alustan erilaisten vanhojen tilojen kanssa .

Esimerkiksi 16-bittisellä x86 - yhteensopivalla alustalla on kuusi muistimallia. Ne määrittävät, mitä oletuksia tehdään oletusrekisterisegmentistä ja osoittimen koosta.

Muistin segmentointi

16-bittinen x86 - arkkitehtuuri mahdollistaa neljän segmenttirekisterin läsnäolon ansiosta samanaikaisen pääsyn neljään muistisegmenttiin. Segmenttirekisterien käyttötarkoitus:

Tällaisella alustalla on tapana kirjoittaa looginen osoite segmentillä : offset , jossa segmentti ja offset annetaan heksadesimaalimuodossa .

Reaalitilassa muistitavun fyysisen osoitteen laskemiseksi vastaavan segmenttirekisterin arvoa siirretään vasemmalle 4 bittiä ja sitten offset lisätään.

Esimerkiksi looginen osoite 7522:F139 antaa 20-bittisen fyysisen osoitteen:

75220 + F139 = 84359

On huomattava, että tämä prosessi johtaa muistin aliasointiin , eli millä tahansa fyysisellä osoitteella voi olla useita loogisia esityksiä. Tämä tekee osoittimien vertailusta vaikeampaa.

Suojatussa tilassa GDT :tä ja LDT :tä käytetään samaan tarkoitukseen .

Osoittimen mitat

Osoittimet voivat olla tyyppiä lähellä (lähellä), kaukana (kaukana) tai suuria (iso).

Lähiosoitin viittaa nykyiseen segmenttiin, joten DS:n tai CS: n ei pitäisi muuttua, kun osoittimeen viitataan. Tämän tyyppiset osoittimet ovat nopeimpia, mutta rajoittuvat 64 kilotavun muistin osoitinalueeseen (eli nykyiseen segmenttiin).

Kauko - osoittimet sisältävät uuden DS- tai CS-arvon. Niiden käyttäminen edellyttää rekisterin vaihtamista, muistin viittausten poistamista ja sitten rekisterin palauttamista. Tällaiset osoittimet voivat osoittaa 1 megatavun muistiin. On huomattava, että aritmeettiset operaatiot osoittimilla (yhteen- ja vähennyslasku) eivät muuta osoittimen segmentin osaa, vaan vaikuttavat vain sen siirtymään. Nollan tai 65535:n (0xFFFF) ulkopuolella toimiville toiminnoille suoritetaan modulo 64K -toiminto, aivan kuten kaikki normaalit 16-bittiset toiminnot. Esimerkiksi signed −1 muuttuu allekirjoittamattomaksi 0xFFFF tai 65535.

Esimerkiksi seuraava koodi menee soveltamisalan ulkopuolelle ja korvaa itsensä:

char far * myfarptr = ( char far * ) 0x50000000L ; allekirjoittamaton pitkä laskuri ; for ( laskuri = 0 ; laskuri < 128 * 1024 ; laskuri ++ ) // käyttää 128K muistia * ( myfarptr + laskuri ) = 7 ; // kirjoita siihen kaikki seitsemän

Jossain vaiheessa laskuri on yhtä suuri kuin (0x10000), ja tuloksena oleva absoluuttinen osoite ylittää 0x5000:0000.

Valtavat osoittimet ovat pohjimmiltaan kaukaisia ​​osoittimia, mutta ne normalisoidaan joka kerta, kun ne muuttuvat, jotta niillä on korkein segmentti, jonka ne voivat osoittaa. Tämä on melko hidasta, mutta se mahdollistaa osoittimen osoittamisen useisiin segmentteihin, ja se mahdollistaa myös tarkemman osoittimien vertailun, ikään kuin alusta olisi litteä muistimalli : tämä poistaa yllä mainitun muistin aliasoinnin käytöstä, joten kaksi suurta osoitinta osoittaminen yhteen ja samaan muistiin on aina yhtä suuri.

Muistimallit

Muistimallit ovat:

Malli Data Koodi
Pikkuruinen* lähellä
pieni kiinni** lähellä
Keskikokoinen lähellä kaukana
Kompakti kaukana lähellä
Suuri kaukana kaukana
Valtava valtava valtava

* Tiny-mallissa kaikki neljä segmenttirekisteriä osoittavat samaan segmenttiin.

** Kaikissa malleissa, joissa on lähellä dataosoittimia, SS on yhtä suuri kuin DS .

Muut alustat

Suojatussa tilassa segmenttiä ei voi ylikirjoittaa, lukea tai suorittaa.

Siksi Small- ja Tiny-muistimalleja toteutettaessa koodisegmenttirekisterin on osoitettava samaan fyysiseen osoitteeseen ja sillä on oltava sama rajoitus kuin datasegmenttirekisterillä. Tämä eliminoi yhden 80286-prosessorin ominaisuuksista , joka varmistaa, että datasegmenttejä ei koskaan suoriteta ja koodisegmenttejä ei koskaan kirjoiteta päälle (mikä tarkoittaa, että itsemuovautuva koodi on kokonaan kielletty ). 80386-prosessoreissa , joissa on litteä muistimalli, on kuitenkin mahdollista kirjoittaa yksittäisiä muistisivuja.

Muistimallit eivät rajoitu 16-bittisiin ohjelmiin. Segmentointia on mahdollista käyttää myös 32-bittisessä suojatussa tilassa (jolloin saadaan 48-bittisiä osoittimia), ja sitä tukevat C- kääntäjät .

Segmentointi 32-bittisessä tilassa ei kuitenkaan salli pääsyä enempään osoiteavaruuteen kuin se, joka kattaa yhden segmentin, paitsi joitain segmenttejä, jotka eivät aina ole edustettuina muistissa, ja lineaarista osoiteavaruutta käytetään yksinkertaisesti välimuistina lisääntyneen osan vuoksi. segmentoitu virtuaalitila.

Suurimmaksi osaksi tämä mahdollistaa paremman suojan eri kohteiden pääsylle (enintään 1 megatavun kokoiset alueet voivat hyötyä tavu-tavulta jakamisesta, toisin kuin yksittäinen melko "karkea" 4 KiB:n jako). sivu), joten sitä käytetään vain erikoissovelluksissa, kuten tietoliikenneohjelmistoissa.

Teknisesti "tasainen" 32-bittinen osoiteavaruus on "pieni" muistimalli segmentoidulle osoiteavaruudelle. Molempien tekijöiden vaikutuksesta kaikki neljä segmenttirekisteriä sisältävät saman arvon.

x86-64 - alustalla on seitsemän muistimallia [1] , joissa useimmat symboliset linkit ovat vain 32-bittisiä ja jos osoite tiedetään linkin hetkellä (toisin kuin sijainnista riippumaton koodi ). Tämä ei vaikuta osoittimien käyttöön, jotka ovat aina tasaisia ​​64-bittisiä osoittimia, vaan ainoastaan ​​arvon saannin kannalta merkkien allokoinnin kautta.

Katso myös

Muistiinpanot

  1. アーカイブされたコピー. Haettu 26. syyskuuta 2010. Arkistoitu alkuperäisestä 16. heinäkuuta 2011.

Kirjallisuus

  • Turbo C++ -version 3.0 käyttöopas . Borland International, 1992.