"FS" / "GS" yazmacının amacı nedir?


105

Bu nedenle, aşağıdaki kayıtların ve kullanımlarının ne olması gerektiğini biliyorum:

  • CS = Kod Segmenti (IP için kullanılır)

  • DS = Veri Segmenti (MOV için kullanılır)

  • ES = Hedef Segment (MOVS vb. İçin kullanılır)

  • SS = Yığın Segmenti (SP için kullanılır)

Ancak aşağıdaki yazmaçların ne için kullanılması amaçlanmıştır?

  • FS = "Dosya Segmenti"?

  • GS = ???

Not: Ben yaşıyorum değil , herhangi bir işletim sistemi hakkında soran - Onların CPU tarafından kullanılmak üzere, amaçlarının soruyorum, eğer bir şey.


25
Bildiğim kadarıyla, bu ikisindeki F ve G hiçbir şeyi temsil etmiyor. Sadece CPU'da (ve komut setinde) altı kullanıcı tanımlı segment kaydı için yer vardı ve birisi "S" tack segmentinin yanı sıra "C" ve "D" harflerinin (kod ve veri) olduğunu fark etti. Sırayla "E" "ekstra" segmentti ve ardından "F" ve "G" sırayla geldi.
torek

3
Olabilirdi, o sırada siz orada olmadığınız sürece başka birinin kafasında neler olup bittiğini bilmek her zaman zordur (ve ben diğer sahildeydim, Intel'in tasarım ekibinin yakınında bile değildim).
torek

21
BS siciliyle ne kadar eğlenmiş olabileceğimizi bir düşünün: -}
Ira Baxter

5
GS'yi her zaman "Grafik Segmenti" olarak kullandım. :-)
Brian Knoblauch

3
"G" eneral "S" egmentine ne dersiniz?
SS Anne

Yanıtlar:


113

Ne için tasarlandıkları ve Windows ve Linux tarafından ne için kullanıldıkları var.

Segment kayıtlarının arkasındaki asıl amaç, bir programın bağımsız olması ve kalıcı bir sanal deponun parçası olması amaçlanan birçok farklı (büyük) bellek segmentine erişmesine izin vermekti. Fikir, dosyaları basitçe adreslenebilir bellek bölümleri olarak değerlendiren 1966 Multics işletim sisteminden alındı. BS yok "Dosya aç, kaydı yaz, dosyayı kapat", sadece kirli sayfa temizlemeyle "Bu değeri sanal veri segmentinde sakla".

Mevcut 2010 işletim sistemlerimiz geriye doğru atılmış dev bir adımdır, bu yüzden bunlara "Hadım" denmektedir. Yalnızca ele alabilir senin bir sözde "düz (IMHO donuk) adres alanı" vererek, süreç mekanın tek bir segment. X86-32 makinesindeki segment kayıtları hala gerçek segment kayıtları için kullanılabilir, ancak kimse rahatsız etmedi (eski Intel başkanı Andy Grove, geçen yüzyılda Intel mühendislerinin tüm bu enerji harcadıktan sonra anladığında oldukça ünlü bir halk uyumu geçirdi ve parası bu özelliği uygulamak için kimsenin kullanmayacağı anlamına geliyordu. Hadi Andy!)

64 bite giden AMD, Multics'i bir seçenek olarak ortadan kaldırıp kaldırmamalarını umursamadığına karar verdi (bu hayırsever yorum; acımasız olanı Multics hakkında bilgisiz olmalarıdır) ve bu nedenle 64 bit modundaki segment kayıtlarının genel yeteneklerini devre dışı bıraktı. Hala iş parçacığı yerel depoya erişmek için evrelere ihtiyaç vardı ve her evre yerel depoyu işlemek için hemen erişilebilir evre durumunda (örneğin kayıtlarda) bir yere ... bir göstericiye ihtiyaç duyuyordu. Windows ve Linux, 32 bit sürümünde bu amaçla hem FS hem de GS (açıklama için Nick teşekkürler) kullandığından, AMD 64 bit segment kayıtlarının (GS ve FS) esasen yalnızca bu amaç için kullanılmasına izin vermeye karar verdi ( onları işlem alanınızda herhangi bir yere işaret edebilir; uygulama kodunun bunları yükleyip yükleyemeyeceğini bilin).

Her iş parçacığının bellek haritasının, iş parçacığı yerel depolaması olan mutlak bir sanal adrese (örneğin, 0-FFF) sahip olması mimari açıdan daha güzel bir IMHO olurdu ([segment] kayıt işaretçisi gerekmez!); Bunu 1970'lerde 8 bitlik bir işletim sisteminde yaptım ve çalışmak için başka bir büyük kayıt yığınına sahip olmak gibi son derece kullanışlıdır.

Dolayısıyla, segment kayıtları artık sizin ekiniz gibi. Körelmiş bir amaca hizmet ederler. Toplu kaybımıza.

Tarihi bilmeyenler onu tekrar etmeye mahkum değiller; aptalca bir şey yapmaya mahkumdurlar.


11
@supercat: 65536 kat daha fazla depolamayı ele almalarına izin veren daha basit, daha parlak bir şema, segment kayıtlarını alt 16 bitin tam üst 16 bit uzantısı olarak ele almak olurdu, bu da özünde 286, 386 ve Multics yaptı.
Ira Baxter

5
@IraBaxter: Bu yaklaşımla ilgili sorun, 80286 tarzı segmentlerin, her segmentte çok sayıda nesneyi depolamak zorunda kalan bir uçtan yeterince yüksek bir ek yüke sahip olması ve böylece her işaretçide hem segmenti hem de ofseti depolamasıdır. Bunun tersine, bellek ayırmalarını 16 baytın katlarına yuvarlamak istiyorsa, 8086 tarzı bölümleme, bir nesneyi tanımlamanın bir yolu olarak parçanın tek başına kullanılmasına izin verir . Tahsislerin 16 bayta yuvarlanması 1980'de biraz rahatsız edici olabilirdi, ancak her nesne referansının boyutunu 8 bayttan dörde düşürürse bugün bir kazanımı temsil ederdi.
supercat

3
Bu kayıtlar vardır modern işletim sistemlerinde kullanılan. Çoğunlukla, en azından şu anda x86 yongaları için mevcut olan iki ana işletim sisteminde görev kontrol blokları hakkındaki bilgilere işaret etmeye adanmıştır. Ve artık orijinal amaçları için bile "genel amaçlı" olmadıklarından, onları çok fazla kullanamazsınız. X86-64 sistemlerinde, iş parçacığı kontrol bloklarında erişmenize izin verdikleri bilgilere ihtiyaç duyana kadar var olmadıklarını varsaymak daha iyidir.
Ira Baxter

5
Ek analojisi, modası geçmiş bilime dayalı olarak gerçekten kötüdür; bağışıklık sistemiyle ilgili, bu yüzden kesinlikle "körelmiş" değil . Gerçek gönderiden uzaklaşır. Bunun dışında iyi bir cevap.
code_dredd

5
Parçalı ve düz belleğin eğlenceli, engelsiz muamelesi için teşekkürler :) 6809 (sayfalı bellek ile ve olmadan), 6502, z80, 68k ve 80 [123]? 86 üzerine kod yazmış olmak, benim bakış açım bu bölümlere ayrılmış hafıza bir korku şovu ve tarihin çöplüğüne gönderilmesine sevindim. Thread_local verilerine verimli erişim için FS ve GS kullanımı, tarihsel bir hatanın mutlu ve istenmeyen bir sonucudur.
Richard Hodges

46

Kayıtlar FSve GSsegment kayıtlarıdır. İşlemci tanımlı bir amacı yoktur, bunun yerine işletim sistemi tarafından çalıştırılan amaçlara sahiptir. Windows 64-bit'te GSkayıt, işletim sistemi tarafından tanımlanan yapılara işaret etmek için kullanılır. FSve GSgenellikle iş parçacığına özgü belleğe erişmek için işletim sistemi çekirdekleri tarafından kullanılır. Windows'ta GSkayıt, iş parçacığına özgü belleği yönetmek için kullanılır. Linux çekirdeği, GScpu'ya özgü belleğe erişmek için kullanır .


1
İşletim sistemi tanımlı amaçlar için veya *dest++ = lookup[*src++];dest, arama ve src birbiriyle ilgisiz üç yerde olsaydı, aksi takdirde oldukça garip olacak bir şey yapması gereken kodu kolaylaştırmak için mi kullanılması amaçlanmıştı ?
supercat

8
Windows'ta FS gerçekten iş parçacığına özel depolama içindir. FS tarafından işaret edilen bloğun belgelenmiş haritasına buradan bakın en.wikipedia.org/wiki/Win32_Thread_Information_Block
Nedko

2
Yalnızca Windows'ta değil. GS, OS X'de TLS için de kullanılır. GS, 64bit çekirdekler tarafından içerik anahtarları sırasında sistem yapılarının izini sürmek için de kullanılır. İşletim sistemi bu etki için SWAPGS kullanacaktır.
ET

14

FS , Windows işlemlerinde iş parçacığı bilgi bloğuna (TIB) işaret etmek için kullanılır.

tipik bir örnek, içinde bir geri arama işlevine bir işaretçi depolayan ( SEH ) 'dir FS:[0x00].

GS , genellikle iş parçacığı yerel depolamaya (TLS) bir işaretçi olarak kullanılır. ve daha önce görmüş olabileceğiniz bir örnek, yığın kanarya korumasıdır (stackguard), gcc'de şöyle bir şey görebilirsiniz:

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax

2
Bu aslında soruyu cevaplamıyor. Soru Not: Herhangi bir işletim sistemi hakkında sormuyorum - CPU tarafından ne amaçla kullanılmaları gerektiğini soruyorum.
Michael Petch

12
@MichaelPetch ya biliyorum, bu q / s'yi
SO'da okuyanlar

3

Intel Kılavuzuna göre, 64 bit modunda bu kayıtların bazı doğrusal adres hesaplamalarında ek temel kayıtlar olarak kullanılması amaçlanmıştır. Bunu 3.7.4.1 bölümünden aldım (4 hacim setinde sayfa 86). Genellikle CPU bu moddayken, doğrusal adres etkili adresle aynıdır, çünkü bu modda bölümleme genellikle kullanılmaz.

Dolayısıyla bu düz adres alanında, FS ve GS yalnızca yerel verileri değil, belirli işletim sistemi veri yapılarını (sayfa 2793, bölüm 3.2.4) ele almada rol oynar, bu nedenle bu kayıtların işletim sistemi tarafından kullanılması amaçlanmıştır, ancak bu belirli tasarımcılar belirlemek.

Hem 32 hem de 64 bit modlarında geçersiz kılmaları kullanırken bazı ilginç hileler vardır, ancak bu ayrıcalıklı yazılımı içerir.

"Orijinal niyetler" perspektifinden, sadece fazladan kayıtlar olmalarından başka söylemek zor. CPU gerçek adres kipinde olduğunda , bu işlemcinin yüksek hızlı 8086 olarak çalışması gibidir ve bu yazmaçlara bir program tarafından açıkça erişilmesi gerekir. Gerçek 8086 öykünmesi uğruna, CPU'yu sanal 8086 modunda çalıştırırsınız ve bu kayıtlar kullanılmaz.


2

TL; DR;

"FS" / "GS" yazmacının amacı nedir?

Varsayılan veri segmentinin (DS) ötesindeki verilere erişmek için. Tıpkı ES gibi.


Uzun Okuma:

Bu nedenle, aşağıdaki kayıtların ve kullanımlarının ne olması gerektiğini biliyorum:

[...]

Neredeyse, ancak DS 'bazı' Veri Segmenti değil, varsayılan olanıdır. Tüm işlemler varsayılan olarak gerçekleşti mi (* 1). Bu, tüm varsayılan değişkenlerin bulunduğu - esasen datave bss. Bir şekilde x86 kodunun oldukça kompakt olmasının bir nedeni de budur. En sık erişilen (artı kod ve yığın) tüm temel veriler 16 bitlik kısa mesafe içindedir.

ES, diğer her şeye (* 2), 64 KiB DS'nin ötesindeki her şeye erişmek için kullanılır. Bir kelime işlemcinin metni, bir hesap tablosunun hücreleri veya bir grafik programının resim verileri vb. Gibi. Çoğu zaman varsayıldığından farklı olarak, bu verilere çok fazla erişilemez, bu nedenle bir öneke ihtiyaç duymak, daha uzun adres alanları kullanmaktan daha az zarar verir.

Benzer şekilde, dize işlemlerini yaparken DS ve ES'nin yüklenmesi (ve yeniden yüklenmesi) gerekmesi yalnızca küçük bir rahatsızlıktır - bu, en azından zamanının en iyi karakter işleme komut setlerinden biri tarafından dengelenir.

Gerçekten acı veren, kullanıcı verilerinin 64 KiB'yi aşması ve işlemlerin başlatılması gerektiğidir. Bazı işlemler bir seferde tek bir veri öğesi üzerinde yapılırken (düşünün A=A*2), çoğu iki ( A=A*B) veya üç veri öğesi gerektirir ( A=B*C). Bu öğeler farklı segmentlerde bulunuyorsa, ES işlem başına birkaç kez yeniden yüklenecek ve bu da biraz ek yük getirecektir.

Başlangıçta, 8 bitlik dünyadan (* 3) küçük programlarla ve eşit derecede küçük veri kümeleriyle, bu büyük bir mesele değildi, ancak kısa süre sonra büyük bir performans dar boğazına dönüştü ve daha da fazlası için gerçek bir baş belası haline geldi. programcılar (ve derleyiciler). 386 Intel ile nihayet iki segment daha ekleyerek rahatlama sağladı, böylece öğelerin hafızaya yayılmış olduğu tekli , ikili veya üçlü işlemler, ES'yi her zaman yeniden yüklemeden gerçekleşebilirdi.

Programlama (en azından montajda) ve derleyici tasarımı için bu oldukça büyük bir kazançtı. Tabii ki, daha da fazlası olabilirdi, ancak üç ile şişe boynu temelde gitmişti, bu yüzden aşırıya kaçmaya gerek yok.

Bilge bir şekilde adlandırmak gerekirse, F / G harfleri E'den sonraki alfabetik devamlardır. En azından CPU tasarımı açısından hiçbir şey ilişkili değildir.


* 1 - Dizi hedefi için ES kullanımı bir istisnadır, çünkü sadece iki segment kaydı gereklidir. Onlar olmasaydı çok yararlı olmazdı - veya her zaman bir segment önekine ihtiyaç duyarlardı. Şaşırtıcı özelliklerden birini öldürebilir, (tekrar etmeyen) dize komutlarının kullanılması, tek bayt kodlamaları nedeniyle aşırı performansla sonuçlanır.

* 2 - Dolayısıyla, geriye dönüp baktığımızda 'Diğer Her Şey Segmenti', 'Ekstra Segment'ten çok daha iyi bir adlandırma olurdu.

* 3 - 8086'nın yalnızca 8800 bitene kadar bir durdurma boşluğu önlemi olarak tasarlandığını ve esas olarak 8080/85 müşterilerini gemide tutmak için gömülü dünya için tasarlandığını unutmamak önemlidir .


1
Vay canına, tüm bunları açıkladığınız için teşekkürler! Bu çok şeyi açıklıyor ve çok mantıklı! +1
user541686
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.