Model de memorie Intel x86

Modelul de memorie pentru platformele x86  este o modalitate de a specifica ipotezele pe care compilatorul trebuie să le facă atunci când generează cod pentru platforme cu adresare de memorie segmentată sau memorie paginată . Cel mai adesea, termenul este folosit atunci când lucrați cu diferite moduri vechi ale platformei x86 .

De exemplu, există șase modele de memorie pe o platformă compatibilă x86 pe 16 biți. Ele determină ce ipoteze se fac despre segmentul implicit de registru și dimensiunea pointerului.

Segmentarea memoriei

Arhitectura x86 pe 16 biți , datorită prezenței a patru registre de segmente, permite accesul simultan la patru segmente de memorie. Scopul registrelor de segmente:

Pe o astfel de platformă, se obișnuiește să scrieți o adresă logică ca segment : offset , unde segmentul și offset-ul sunt date în notație hexazecimală .

În modul real, pentru a calcula adresa fizică a unui octet de memorie, valoarea registrului de segment corespunzător este deplasată la stânga cu 4 biți, apoi se adaugă offset-ul.

De exemplu, adresa logică 7522:F139 oferă o adresă fizică de 20 de biți:

75220 + F139 = 84359

Trebuie remarcat faptul că acest proces are ca rezultat aliasarea memoriei , adică orice adresă fizică dată poate avea mai multe reprezentări logice. Acest lucru face compararea indicatorilor mai dificilă.

În modul protejat , GDT și LDT sunt utilizate în același scop .

Dimensiunile indicatorului

Indicatoarele pot fi de tipul aproape (aproape), departe (departe) sau uriașe (mari).

Indicatorul apropiat se referă la segmentul curent, deci nici DS, nici CS nu ar trebui să se schimbe atunci când indicatorul este dereferențiat. Pointerii de acest tip sunt cei mai rapidi, dar sunt limitati la o zonă de pointer de 64 de kiloocteți de memorie (adică segmentul curent).

Indicatorii departe conțin noua valoare DS sau CS. Pentru a le utiliza, registrul trebuie schimbat, memoria dereferențiată și apoi registrul trebuie restaurat. Astfel de indicatoare pot indica 1 megaoctet de memorie. Trebuie remarcat faptul că operațiile aritmetice cu pointeri (adunare și scădere) nu schimbă secțiunea segmentului pointerului, ci afectează doar offset-ul acestuia. Operațiile în afara zero sau 65535 (0xFFFF) vor fi supuse unei operații modulo 64K, la fel ca orice operație normală pe 16 biți. De exemplu, semnat -1 devine nesemnat 0xFFFF sau 65535.

De exemplu, următorul cod va ieși din domeniul de aplicare și se va suprascrie:

char far * myfarptr = ( char far * ) 0x50000000L ; contor lung nesemnat ; pentru ( counter = 0 ; counter < 128 * 1024 ; counter ++ ) // acces 128K memorie * ( myfarptr + counter ) = 7 ; // scrie toate șapte în el

La un moment dat, contorul va deveni egal cu (0x10000), iar adresa absolută rezultată va depăși 0x5000:0000.

Indicatorii uriași sunt, în esență, indicatori de departe, dar sunt normalizați de fiecare dată când se schimbă, astfel încât să aibă cel mai înalt segment pe care îl pot adresa. Acest lucru este destul de lent, dar permite unui pointer să indice mai multe segmente și, de asemenea, permite o comparație mai precisă a indicatorilor, ca și cum platforma ar fi un model de memorie plat : acest lucru dezactivează aliasarea memoriei așa cum s-a menționat mai sus, deci două pointere mari arătând spre una și aceeași bucată de memorie va fi întotdeauna egală.

Modele de memorie

Modelele de memorie sunt:

Model Date Codul
mic* aproape
Mic închide** aproape
Mediu aproape departe
Compact departe aproape
Mare departe departe
Imens imens imens

* În modelul Tiny, toate cele patru registre de segment indică același segment.

** În toate modelele cu indicatori aproape de date, SS este egal cu DS .

Alte platforme

În modul protejat, segmentul nu poate fi suprascris, citit sau executat.

Prin urmare, la implementarea modelelor de memorie Small și Tiny, registrul de segment de cod trebuie să indice aceeași adresă fizică și să aibă aceeași constrângere ca și registrul de segment de date. Acest lucru elimină una dintre caracteristicile procesorului 80286 , care asigură că segmentele de date nu sunt niciodată executate și segmentele de cod nu sunt niciodată suprascrise (ceea ce înseamnă că codul cu auto-modificare este complet interzis ). Cu toate acestea, pe procesoarele 80386 cu modelul său de memorie plată, este posibilă protejarea la scriere a paginilor individuale de memorie.

Modelele de memorie nu sunt limitate la programe pe 16 biți. Este posibil să utilizați segmentarea și în modul protejat pe 32 de biți (rezultând pointeri pe 48 de biți), și există compilatoare C care o acceptă.

Cu toate acestea, segmentarea în modul pe 32 de biți nu permite accesul la mai mult spațiu de adrese decât cel care acoperă un segment, cu excepția unor segmente care nu sunt întotdeauna reprezentate în memorie, iar spațiul de adrese liniar este pur și simplu utilizat ca cache datorită creșterii spațiu virtual segmentat.

În cea mai mare parte, acest lucru permite o mai bună protecție a accesului la diferite obiecte (zonele cu dimensiunea de până la 1 megaoctet pot beneficia de împărțirea octet-cu-octet a protecției accesului, spre deosebire de împărțirea destul de „grundă” de 4 KiB oferită de un singur octet. pagina) și, prin urmare, este utilizat numai în aplicații speciale, cum ar fi software-ul de telecomunicații.

Din punct de vedere tehnic, un spațiu de adresă „plat” de 32 de biți este un model de memorie „minut” pentru un spațiu de adrese segmentat. Sub influența ambilor factori, toate cele patru registre de segmente conțin aceeași valoare.

Pe platforma x86-64 , există șapte modele de memorie [1] , majoritatea legăturilor simbolice fiind de numai 32 de biți și dacă adresa este cunoscută la momentul legăturii (spre deosebire de codul independent de poziție ). Acest lucru nu afectează utilizarea pointerilor, care sunt întotdeauna pointeri plate pe 64 de biți, ci doar în ceea ce privește accesul la valoare prin alocare de caractere.

Vezi și

Note

  1. アーカイブされたコピー. Preluat la 26 septembrie 2010. Arhivat din original la 16 iulie 2011.

Literatură

  • Ghidul utilizatorului Turbo C++ Versiunea 3.0 . Borland International, 1992.