x86 bellek segmentasyonu - x86 memory segmentation

x86 bellek segmentasyonu , Intel x86 bilgisayar komut seti mimarisinde bellek segmentasyonunun uygulanması anlamına gelir . Segmentasyon, programların 64 KB'den (65.536 bayt ) fazla belleğe hitap etmesine izin vermenin bir yolu olarak 1978'de  Intel 8086'da tanıtıldı . Intel 80286 desteği eklendi 1982 yılında segmentasyon ikinci versiyonunu tanıttı sanal bellek ve bellek koruması . Bu noktada orijinal model gerçek mod olarak yeniden adlandırıldı ve yeni sürüm korumalı mod olarak adlandırıldı . X86-64 2003 yılında tanıtılan mimarisi, büyük ölçüde 64 bit modunda segmentasyon için destek düştü.

Hem gerçek hem de korumalı modlarda sistem , gerçek bellek adresini türetmek için 16 bitlik segment kayıtlarını kullanır . Gerçek modda, CS, DS, SS ve ES kayıtları, halihazırda kullanılan program kodu segmentine (CS), mevcut veri segmentine (DS), mevcut yığın segmentine (SS) ve programcı tarafından belirlenen bir ekstra segmente işaret eder. (ES). Intel 80386 , 1985 tanıtılan, donanım tarafından tanımlanan özel bir kullanıma sahip, iki ek kademeli kayıtlar, FS ve GS ekler. Segment kayıtlarının kullanılma şekli iki mod arasında farklılık gösterir.

Segment seçimi, normal olarak, yürütülen işleve göre işlemci tarafından varsayılan olarak belirlenir. Talimatlar her zaman kod bölümünden alınır. Herhangi bir yığın push veya pop veya yığına atıfta bulunan herhangi bir veri referansı yığın segmentini kullanır. Verilere yapılan diğer tüm referanslar veri segmentini kullanır. Ekstra segment, dize işlemleri için varsayılan hedeftir (örneğin, MOVS veya CMPS). FS ve GS'nin donanım tarafından atanmış kullanımları yoktur. Talimat formatı, istenirse seçilen talimatlar için varsayılan segmenti geçersiz kılmak için kullanılabilecek isteğe bağlı bir segment önek baytına izin verir .

gerçek mod

Gerçek mod hafızasında üç bölüm (büyütmek için resme tıklayın). Segment 2 ve segment 3 arasında bir örtüşme var; turkuaz alandaki baytlar her iki segment seçiciden de kullanılabilir.

Olarak gerçek mod veya V86 modunda , bir segmente büyüklüğünde 1 arasında olabilir bayt (16 bit teknikleri kullanarak) 65.536 bayta kadar.

Segment kaydındaki 16 bitlik segment seçici, segment adresi olarak adlandırılan doğrusal 20 bitlik bir adresin en anlamlı 16 biti olarak yorumlanır ve kalan dört en az anlamlı bitin tümü sıfırdır. Segment adresi, bu moddaki fiziksel adresle aynı olan doğrusal bir adres elde etmek için talimatta her zaman 16 bitlik bir ofset değerine eklenir . Örneğin, segmentlere ayrılmış 06EFh:1234h adresi (burada "h" soneki onaltılık anlamına gelir ), 06EF0h segment adresini temsil eden, ofsetin eklendiği ve 06EF0h + 1234h = 08124h doğrusal adresini veren bir segment seçiciye sahiptir.

  0000 0110 1110 1111  0000 segment , 16 bit, 4 bit sola kaydırıldı (veya 0x10 ile çarpıldı)
+      0001 0010 0011 0100 Ofset , 16 bit
                          
  0000 1000 0001 0010 0100 adres , 20 bit

Segment adresi ve ofsetin eklenme şekli nedeniyle, tek bir doğrusal adres 2 12 = 4096 farklı segment:offset çiftine eşlenebilir . Örneğin, 08124h doğrusal adresi, 06EFh:1234h, 0812h:0004h, 0000h:8124h, vb. bölümlere ayrılmış adreslere sahip olabilir.

Bu, benzersiz adresleme şemalarına alışmış programcılar için kafa karıştırıcı olabilir, ancak örneğin birden çok iç içe veri yapısını adreslerken avantaj sağlamak için de kullanılabilir. Gerçek kip bölümleri her zaman 64  KB uzunluğunda olsa da, pratik sonuç, her bölümün 64 KB uzunluğunda olması gerektiği yerine hiçbir bölümün 64 KB'den uzun olamayacağıdır. Gerçek modda herhangi bir koruma veya ayrıcalık sınırlaması olmadığı için, bir segment 64 KB'den küçük olarak tanımlanabilse bile, herhangi bir programın yapabileceği gibi, koordine etmek ve segmentlerinin sınırları içinde tutmak tamamen programlara bağlı olacaktır. her zaman herhangi bir belleğe erişin (çünkü bölüm adreslerini kesinlikle denetim olmadan değiştirmek için bölüm seçicileri keyfi olarak ayarlayabilir). Bu nedenle, gerçek mod, her segment için 1 ila 65.536 bayt aralığında, CPU tarafından uygulanmayan değişken bir uzunluğa sahip olarak hayal edilebilir.

(Doğrusal adresin, segmentlere ayrılmış adreslerin ve segment ve ofset alanlarının baştaki sıfırları, netlik için burada gösterilmektedir. Genellikle atlanırlar.)

Gerçek modun etkin 20 bit adres alanı , adreslenebilir belleği 2 20  bayt veya 1.048.576 bayt (1  MB ) ile sınırlar. Bu, doğrudan tam olarak 20 adres pinine sahip olan Intel 8086'nın (ve daha sonra yakından ilişkili 8088'in) donanım tasarımından türetilmiştir . (Her ikisi de 40 pinli DIP paketlerinde paketlenmiştir; sadece 20 adres satırıyla bile, adres ve veri yolları sınırlı pin sayısı dahilindeki tüm adres ve veri hatlarına uyacak şekilde çoğullanmıştır.)

Her segment , doğrusal (düz) adres alanının başlangıcından paragraf adı verilen 16 baytın katlarında başlar . Yani 16 bayt aralıklarla. Tüm segmentler 64 KB uzunluğunda olduğundan, bu, segmentler arasında nasıl örtüşme olabileceğini ve lineer bellek adres alanındaki herhangi bir konuma neden birçok segment:offset çiftiyle erişilebileceğini açıklar. Doğrusal adres alanında bir segmentin başlangıcının gerçek konumu segment×16 ile hesaplanabilir. 0Ch (12) segment değeri, doğrusal adres alanında C0h (192)'de doğrusal bir adres verir. Adres ofseti daha sonra bu numaraya eklenebilir. 0Ch:0Fh (12:15) C0h+0Fh=CFh (192+15=207) olur, CFh (207) doğrusal adres olur. Bu tür adres çevirileri, CPU'nun segmentasyon birimi tarafından gerçekleştirilir. Son segment, FFFFh (65535), 20 bitlik adres alanının bitiminden 16 bayt önce FFFF0h (1048560) doğrusal adresinde başlar ve böylece, 65.536 bayta kadar bir ofset ile 65.520'ye (65536) kadar erişebilir. -16) 20 bit 8088 adres alanının sonunu geçen bayt. 8088'de, bu adres erişimleri, 65535:16, 0 adresine ve 65533:1000, doğrusal adres alanının 952 adresine erişecek şekilde adres alanının başlangıcına sarılmıştır. Bu özelliğin programcılar tarafından kullanılması, daha sonraki CPU nesillerinde Gate A20 uyumluluk sorunlarına yol açtı , burada doğrusal adres alanı 20 biti aştı.

16-bit gerçek modda, uygulamaların birden fazla bellek bölümünden faydalanmasını sağlamak (herhangi bir 64K-segmentinde bulunandan daha fazla belleğe erişmek için) oldukça karmaşıktır, ancak en küçük araçlar dışında herkes için gerekli bir kötülük olarak görülüyordu ( hangi daha az bellek ile yapabilirdi). Sorunun kökü, tüm bellek aralığının düz adreslenmesi için uygun adres aritmetik talimatlarının mevcut olmamasıdır. Düz adresleme, birden fazla talimat uygulayarak mümkündür, ancak bu da daha yavaş programlara yol açar.

Bellek modeli kavramı kesimi kaydeder kurulum türemiştir. Örneğin, küçük CS=DS=SS modelinde , yani programın kodu, verileri ve yığınının tümü tek bir 64 KB segmentinde bulunur. Olarak küçük bellek Model DS = SS, bu nedenle aynı segmentteki hem veri hem de yığın ikamet; CS, 64 KB'ye kadar farklı bir kod segmentine işaret eder.

Korumalı mod

Yerel tanımlayıcı tablosu ile korumalı mod belleğinde üç bölüm (büyütmek için resme tıklayın) .

80286 korumalı mod

80286 'in korumalı mod 2'ye işlemcinin adres alanını genişletir 24 , ancak kaydırma değerini ayarlayarak bayt (16 megabayt). Bunun yerine, 16 bitlik segment kayıtları artık ofsetin eklendiği 24 bitlik baz adresleri içeren bir segment tanımlayıcı tablosuna bir indeks içerir . Eski yazılımı desteklemek için işlemci, 8086'nın parçalı adresleme modelini kullandığı bir mod olan "gerçek mod"da başlar. Ancak küçük bir fark vardır: sonuçta ortaya çıkan fiziksel adres artık 20 bit'e kesilmez, bu nedenle gerçek mod işaretçileri (ancak 8086 işaretçileri değil) artık 100000 16 ile 10FFEF 16 arasındaki adreslere başvurabilir . Bu kabaca 64 kilobaytlık bellek bölgesi, Yüksek Bellek Alanı (HMA) olarak biliniyordu ve DOS'un sonraki sürümleri , mevcut "geleneksel" belleği (yani ilk MB içinde ) artırmak için bunu kullanabilirdi . HMA'nın eklenmesiyle toplam adres alanı yaklaşık 1.06 MB'dir. 80286, gerçek kipteki adresleri 20 bite kesmese de, 80286 içeren bir sistem, 21. adres satırı olan A20 hattını kapatarak, işlemciye harici donanım ile bunu yapabilir . IBM PC AT, bunu yapmak için donanımı sağladı (orijinal IBM PC ve PC/XT modelleri için yazılımla tam geriye dönük uyumluluk için ) ve böylece sonraki tüm " AT sınıfı" PC klonları da yaptı.

286 korumalı mod, 8086/88 makineli geniş kullanıcı kitlesini dışlayacağından nadiren kullanıldı. Ayrıca, gerçek modda olduğu gibi, belleği 64 bin parçaya bölmeyi hala gerektiriyordu. Bu sınırlama, boyutu 64k'dan daha büyük olan bellek işaretçilerinin kullanımına izin veren 32-bit CPU'larda çözülebilir, ancak Segment Limit alanı yalnızca 24 bit uzunluğunda olduğundan, oluşturulabilecek maksimum segment boyutu 16MB'dir (sayfa daha fazla bellek ayırmak için kullanılabilir, tek bir segment 16MB'yi aşamaz). Bu yöntem, düz bir bellek alanı oluşturmak için Windows 3.x uygulamalarında yaygın olarak kullanılıyordu, ancak işletim sisteminin kendisi hala 16 bit olduğundan, 32 bit yönergelerle API çağrıları yapılamıyordu. Bu nedenle, API çağrıları yapan tüm kodları 64k segmentlere yerleştirmek hala gerekliydi.

286 korumalı mod bir kez çağrıldığında, donanım sıfırlaması yapılması dışında bu moddan çıkılamadı. Yükselen IBM PC/AT standardını takip eden makineler , standart klavye denetleyicisi aracılığıyla CPU'ya sıfırlama yapıyormuş gibi yapabilirdi, ancak bu önemli ölçüde ağırdı. Windows 3.x , CPU'nun kesme işleme mekanizmalarında kasıtlı olarak üçlü bir hatayı tetikleyerek bu sorunların her ikisinden de kurtuldu ve bu da CPU'nun neredeyse anında gerçek moda düşmesine neden oldu.

Ayrıntılı Segmentasyon Birimi İş Akışı

Mantıksal bir adres, 16 bitlik bir segment seçiciden (13+1 adres biti sağlayan) ve 16 bitlik bir ofsetten oluşur. Segment seçici, segment kayıtlarından birinde bulunmalıdır. Bu seçici, 2 bitlik Talep Edilen Ayrıcalık Düzeyi (RPL), 1 bitlik Tablo Göstergesi (TI) ve 13 bitlik bir dizinden oluşur.

Belirli bir mantıksal adresin adres çevirisini denediğinde, işlemci , TI=0 olduğunda Global Tanımlayıcı Tablodan veya TI=1 olduğunda Yerel Tanımlayıcı Tablodan 64-bit segment tanımlayıcı yapısını okur . Daha sonra ayrıcalık kontrolünü gerçekleştirir:

max(CPL, RPL) ≤ DPL

burada CPL geçerli ayrıcalık düzeyidir (CS kaydının alt 2 bitinde bulunur), RPL, bölüm seçiciden istenen ayrıcalık düzeyidir ve DPL, bölümün tanımlayıcı ayrıcalık düzeyidir (tanımlayıcıda bulunur). Tüm ayrıcalık seviyeleri, en düşük sayının en yüksek ayrıcalığa karşılık geldiği 0-3 aralığında tam sayılardır.

Eşitsizlik yanlışsa, işlemci bir genel koruma (GP) hatası oluşturur . Aksi halde adres çevirisi devam eder. İşlemci daha sonra 32 bit veya 16 bit ofseti alır ve bunu segment tanımlayıcısında belirtilen segment limitiyle karşılaştırır. Daha büyükse, bir GP hatası oluşturulur. Aksi takdirde, işlemci, tanımlayıcıda belirtilen 24 bitlik segment tabanını ofsete ekleyerek doğrusal bir fiziksel adres oluşturur.

Ayrıcalık kontrolü, yalnızca segment kaydı yüklendiğinde yapılır, çünkü segment tanımlayıcıları segment kayıtlarının gizli bölümlerinde önbelleğe alınır.

80386 korumalı mod

In Intel 80386 ve üstü, korumalı mod 80286 korumalı modu segmentasyon mekanizmasını korur, ancak bir çağrı birimi segmentasyon ünitesi ve fiziksel veri yolu arasındaki adresi çevirinin ikinci katman olarak eklenmiştir. Ayrıca, daha da önemlisi, adres ofsetleri 32-bit (16-bit yerine) ve her bölüm tanımlayıcısındaki bölüm tabanı da 32-bit (24-bit yerine). Segmentasyon biriminin genel çalışması aksi takdirde değişmez. Çağrı birimi etkinleştirilebilir veya devre dışı bırakılabilir; devre dışı bırakılırsa, işlem 80286'dakiyle aynıdır. Çağrı birimi etkinleştirilirse, bir segmentteki adresler, 80286'da olduğu gibi fiziksel adresler yerine artık sanal adreslerdir. Yani, segment başlangıç ​​adresi, ofset, ve son 32-bit adresi, ikisi eklenerek türetilen bölümleme birimi, çağrı birimi etkinleştirildiğinde tümü sanal (veya mantıksal) adreslerdir. Segmentasyon birimi bu 32-bit sanal adresleri oluşturduğunda ve doğruladığında, etkinleştirilmiş çağrı birimi nihayet bu sanal adresleri fiziksel adreslere çevirir. Fiziksel adresler üzerinde 32 bit olan 386 ama destekleyen yeni işlemciler üzerinde büyük olabilir Fiziksel Adres Uzantısı .

80386 ayrıca iki yeni genel amaçlı veri segmenti kaydı olan FS ve GS'yi orijinal dört segment kaydı grubuna (CS, DS, ES ve SS) tanıttı.

Bir 386 CPU, CR0 kontrol kaydındaki bir bit temizlenerek gerçek moda geri alınabilir, ancak bu, güvenlik ve sağlamlığı zorlamak için ayrıcalıklı bir işlemdir. Karşılaştırma yoluyla, bir 286 yalnızca, örneğin üçlü bir hata veya harici donanım kullanılarak bir işlemci sıfırlaması zorlanarak gerçek moda döndürülebilir .

Daha sonraki gelişmeler

X86-64 mimarisi uzun modunda (64 bit modu) segmentasyon kullanmaz. Segment kayıtlarından dördü, CS, SS, DS ve ES, 0'a ve sınır 2 64'e zorlanır . Segment kayıtları FS ve GS yine de sıfırdan farklı bir temel adrese sahip olabilir. Bu, işletim sistemlerinin bu segmentleri özel amaçlar için kullanmasına izin verir. Eski modlar tarafından kullanılan genel tanımlayıcı tablo mekanizmasının aksine, bu bölümlerin temel adresi modele özgü bir kayıtta saklanır . x86-64 mimarisi ayrıca , çekirdek modu ve kullanıcı modu temel adreslerinin değiştirilmesine izin veren özel SWAPGS talimatını sağlar .

Örneğin , x86-64 üzerindeki Microsoft Windows , istisna işleme, iş parçacığı yerel değişkenleri ve diğer iş parçacığı başına durum hakkında bilgi içeren her iş parçacığı için küçük bir veri yapısı olan İş Parçacığı Ortam Bloğuna işaret etmek için GS segmentini kullanır . Benzer şekilde, Linux çekirdeği , CPU başına verileri depolamak için GS segmentini kullanır.

GS / FS kullanılan gcc 'in parçacığı yerel depolama ve kanarya bazlı yığın koruyucusu.

Uygulamalar

Mantıksal adresler x86 derleme dilinde açıkça belirtilebilir , örneğin (AT&T sözdizimi):

movl $42, %fs:(%eax)  ; Equivalent to M[fs:eax]<-42) in RTL

veya Intel sözdiziminde :

mov dword [fs:eax], 42

Ancak, segment kayıtları genellikle örtük olarak kullanılır.

  • Tüm CPU talimatları , CS kaydında tutulan segment seçici tarafından belirtilen kod segmentinden dolaylı olarak alınır .
  • Çoğu bellek referansı , DS kaydında tutulan bölüm seçici tarafından belirtilen veri bölümünden gelir . Bunlar ayrıca, hafıza referansını yapan talimattan önce bir segment geçersiz kılma öneki geliyorsa, ES kaydında tutulan segment seçici tarafından belirtilen ekstra segmentten gelebilir. Varsayılan olarak DS'yi kullanan talimatların tümü olmasa da çoğu, bir ES geçersiz kılma önekini kabul eder.
  • İşlemci yığın referansları, dolaylı olarak (örneğin push ve pop talimatları) veya açıkça ( (E)SP veya (E)BP kayıtları kullanılarak bellek erişimleri) , SS kaydında tutulan segment seçici tarafından belirtilen yığın segmentini kullanır .
  • Dizi komutları (örneğin stos , movs ), veri segmenti ile birlikte ES kaydında tutulan segment seçici tarafından belirtilen ekstra segmenti de kullanır .

Segmentasyon, x86-32 işlemcilerde kapatılamaz (bu, 64-bit modu için de geçerlidir, ancak tartışma kapsamının dışındadır), pek çok 32-bit işletim sistemi, tüm segmentlerin tabanlarını 0'a ayarlayarak düz bellek modelini simüle eder. Segmentasyonu programlara nötr hale getirmek için. Örneğin, Linux çekirdeği yalnızca 4 genel amaçlı bölüm kurar:

İsim Açıklama Temel sınır DPL
__KERNEL_CS Çekirdek kodu segmenti 0 4 GiB 0
__KERNEL_DS Çekirdek veri segmenti 0 4 GiB 0
__USER_CS Kullanıcı kodu segmenti 0 4 GiB 3
__USER_DS Kullanıcı verileri segmenti 0 4 GiB 3

Taban her durumda 0'a ve 4 GiB sınırına ayarlandığından, segmentasyon birimi, program sorunlarının çağrı birimine ulaşmadan önce adreslerini etkilemez . (Bu, elbette, önceki x86 işlemcilerin bir çağrı birimine sahip olmadığı için 80386 ve sonraki işlemcileri ifade eder.)

Mevcut Linux, iş parçacığı yerel depolamasına işaret etmek için GS'yi de kullanır .

Segmentler, kod, veri veya sistem segmentleri olarak tanımlanabilir. Segmentleri salt okunur, okuma/yazma, yürütme vb. yapmak için ek izin bitleri mevcuttur.

Korumalı modda, kod her zaman CS ( kod segment seçicisi) hariç tüm segment kayıtlarını değiştirebilir . Bunun nedeni, işlemcinin mevcut ayrıcalık seviyesinin (CPL) CS kaydının alt 2 bitinde saklanmasıdır. İşlemci ayrıcalık düzeyini yükseltmenin (ve CS'yi yeniden yüklemenin) tek yolu lcall (far call) ve int (interrupt) talimatlarıdır. Benzer şekilde, ayrıcalık seviyesini düşürmenin (ve CS'yi yeniden yüklemenin) tek yolu lret (uzak dönüş) ve iret (kesinti dönüşü) komutlarıdır. Gerçek modda kod, uzak bir atlama yaparak (veya 8086 veya 8088'de belgelenmemiş bir talimat kullanarak) CS kaydını da değiştirebilir . Tabii ki, gerçek modda ayrıcalık seviyeleri yoktur; tüm programlar, tüm belleğe ve tüm CPU talimatlarına mutlak kontrolsüz erişime sahiptir. POP CS

Segmentasyon hakkında daha fazla bilgi için AMD veya Intel web sitelerinde ücretsiz olarak bulunan IA-32 kılavuzlarına bakın .

Notlar ve referanslar

Ayrıca bakınız

Dış bağlantılar