Wiem więc, jakie mają być następujące rejestry i ich zastosowania:
CS = Segment kodu (używany dla IP)
DS = Segment danych (używany dla MOV)
ES = Segment docelowy (używany w przypadku MOVS itp.)
SS = Segment stosu (używany dla SP)
Ale do czego służą poniższe rejestry?
FS = "Segment pliku"?
GS = ???
Uwaga: nie pytam o żaden konkretny system operacyjny - pytam o to, do czego miały być używane przez procesor, jeśli w ogóle.
Odpowiedzi:
Jest do czego były przeznaczone i do czego są używane w systemach Windows i Linux.
Pierwotnym zamiarem stojącym za rejestrami segmentowymi było umożliwienie programowi dostępu do wielu różnych (dużych) segmentów pamięci, które miały być niezależne i stanowić część trwałego magazynu wirtualnego. Pomysł zaczerpnięto z systemu operacyjnego Multics z 1966 roku , w którym pliki były po prostu adresowalnymi segmentami pamięci. Brak BS „Otwórz plik, zapisz rekord, zamknij plik”, po prostu „Zapisz tę wartość w tym wirtualnym segmencie danych” z brudnym opróżnianiem strony.
Nasze obecne systemy operacyjne na rok 2010 to ogromny krok wstecz, dlatego nazywają się „Eunuchs”. Można tylko zająć twojego pojedynczego segmentu kosmicznego procesowego, dając tak zwany „płaski (IMHO matowa) przestrzeni adresowej”. Rejestry segmentowe na maszynie x86-32 mogą być nadal używane do prawdziwych rejestrów segmentowych, ale nikt się tym nie przejmował (Andy Grove, były prezes Intela, miał dość słynne publiczne dopasowanie w zeszłym wieku, kiedy zorientował się, że wszyscy inżynierowie Intela zużyli energię i jego pieniądze na wdrożenie tej funkcji, że nikt nie będzie z niej korzystał. Idź, Andy!)
AMD, idąc na 64 bity, zdecydowało, że nie obchodzi ich, czy wyeliminują Multics jako wybór (taka jest charytatywna interpretacja; nieżyczliwa jest to, że nie mają pojęcia o Multics), a więc wyłączyli ogólną możliwość rejestrów segmentowych w trybie 64-bitowym. Wciąż istniała potrzeba wątków, aby uzyskać dostęp do lokalnego magazynu wątków, a każdy wątek potrzebował wskaźnika ... gdzieś w natychmiast dostępnym stanie wątku (np. W rejestrach) ... do wątku w lokalnym magazynie. Ponieważ zarówno Windows, jak i Linux używały FS i GS (dzięki Nickowi za wyjaśnienie) do tego celu w wersji 32-bitowej, AMD zdecydowało się pozwolić, aby 64-bitowe rejestry segmentowe (GS i FS) były używane zasadniczo tylko do tego celu (myślę, że można ustaw je w dowolnym miejscu w przestrzeni procesu; nie wiem, czy kod aplikacji może je załadować, czy nie).
Byłoby ładniejszym architektonicznie IMHO, gdyby mapa pamięci każdego wątku miała bezwzględny adres wirtualny (np. 0-FFF powiedz), który był jego lokalną pamięcią wątku (nie jest potrzebny wskaźnik rejestru [segment]!); Zrobiłem to w 8-bitowym systemie operacyjnym w latach siedemdziesiątych i było to niezwykle przydatne, jak posiadanie kolejnego dużego stosu rejestrów do pracy.
Zatem rejestry segmentowe są teraz trochę podobne do twojego dodatku. Służą szczątkowemu celowi. Za naszą zbiorową stratę.
Ci, którzy nie znają historii, nie są skazani na jej powtarzanie; są skazani na zrobienie czegoś głupszego.
źródło
Rejestry
FS
iGS
są rejestrami segmentowymi. Nie mają celu zdefiniowanego przez procesor, ale zamiast tego są nadawane przez system operacyjny, który je uruchamia. W 64-bitowym systemie WindowsGS
rejestr służy do wskazywania struktur zdefiniowanych w systemie operacyjnym.FS
iGS
są powszechnie używane przez jądra systemu operacyjnego do uzyskiwania dostępu do pamięci specyficznej dla wątków. W systemie WindowsGS
rejestr służy do zarządzania pamięcią specyficzną dla wątków. Jądro Linuksa używaGS
do uzyskania dostępu do pamięci specyficznej dla procesora.źródło
*dest++ = lookup[*src++];
innym przypadku byłby raczej niezręczny, gdyby dest, lookup i src znajdowały się w trzech niepowiązanych lokalizacjach.FS służy do wskazywania bloku informacji o wątku (TIB) w procesach systemu Windows.
jednym typowym przykładem jest ( SEH ), który przechowuje wskaźnik do funkcji zwrotnej w
FS:[0x00]
.GS jest powszechnie używany jako wskaźnik do lokalnego magazynu wątków (TLS). a jednym przykładem, który mogłeś zobaczyć wcześniej, jest ochrona stosu (stackguard), w gcc możesz zobaczyć coś takiego:
źródło
Zgodnie z podręcznikiem Intela, w trybie 64-bitowym rejestry te mają być używane jako dodatkowe rejestry bazowe w niektórych obliczeniach adresu liniowego. Wyciągnąłem to z sekcji 3.7.4.1 (str. 86 w zestawie 4 tomów). Zwykle, gdy procesor jest w tym trybie, adres liniowy jest taki sam jak adres efektywny, ponieważ segmentacja często nie jest używana w tym trybie.
Tak więc w tej płaskiej przestrzeni adresowej FS i GS odgrywają rolę w adresowaniu nie tylko danych lokalnych, ale niektórych struktur danych systemu operacyjnego (str. 2793, sekcja 3.2.4), zatem te rejestry były przeznaczone do wykorzystania przez system operacyjny, jednak ci konkretni projektanci określać.
Istnieje kilka interesujących sztuczek podczas używania nadpisań w obu trybach 32 i 64-bitowych, ale dotyczy to uprzywilejowanego oprogramowania.
Z punktu widzenia „oryginalnych intencji”, trudno powiedzieć inaczej niż są to tylko dodatkowe rejestry. Kiedy procesor jest w trybie adresu rzeczywistego , jest to tak, jakby procesor działał jako szybki 8086 i te rejestry muszą być jawnie dostępne przez program. Ze względu na prawdziwą emulację 8086 procesor uruchomiłbyś w trybie virtual-8086 i te rejestry nie byłyby używane.
źródło
TL; DR;
Po prostu dostęp do danych poza domyślnym segmentem danych (DS). Dokładnie jak ES.
Długa lektura:
Cóż, prawie, ale DS nie jest „jakimś” segmentem danych, ale domyślnym. Czy wszystkie operacje odbywały się domyślnie (* 1). To jest miejsce, w którym znajdują się wszystkie domyślne zmienne - zasadniczo
data
ibss
. W pewnym sensie jest to jeden z powodów, dla których kod x86 jest raczej zwarty. Wszystkie istotne dane, które są najczęściej używane (plus kod i stos), znajdują się w odległości 16-bitowej.ES jest używany do uzyskiwania dostępu do wszystkiego innego (* 2), wszystkiego poza 64 KiB DS. Podobnie jak tekst w edytorze tekstu, komórki arkusza kalkulacyjnego lub dane obrazu w programie graficznym i tak dalej. W przeciwieństwie do często zakładanych danych, dostęp do tych danych nie jest tak duży, więc potrzeba prefiksu jest mniej bolesna niż używanie dłuższych pól adresowych.
Podobnie jest tylko niewielką irytacją, że DS i ES mogą być ładowane (i ponownie ładowane) podczas wykonywania operacji na łańcuchach - jest to przynajmniej kompensowane przez jeden z najlepszych zestawów instrukcji obsługi znaków w tamtych czasach.
To, co naprawdę boli, to sytuacja, gdy dane użytkownika przekraczają 64 KB i trzeba rozpocząć operacje. Podczas gdy niektóre operacje są po prostu wykonywane na pojedynczym elemencie danych na raz (pomyśl
A=A*2
), większość wymaga dwóch (A=A*B
) lub trzech elementów danych (A=B*C
). Jeśli te elementy znajdują się w różnych segmentach, ES będzie przeładowywana kilka razy na operację, co zwiększy nieco narzut.Na początku, z małymi programami ze świata 8-bitowego (* 3) i równie małymi zestawami danych, nie było to nic wielkiego, ale wkrótce stało się to wąskim gardłem o dużej wydajności - a tym bardziej prawdziwym bólem w dupie dla programiści (i kompilatorzy). Dzięki procesorowi 386 Intel w końcu zapewnił ulgę, dodając dwa kolejne segmenty, więc każda szeregowa operacja jednoargumentowa , binarna lub trójskładnikowa z elementami rozłożonymi w pamięci mogła odbywać się bez ciągłego przeładowywania ES.
W przypadku programowania (przynajmniej w asemblerze) i projektowania kompilatorów było to spore korzyści. Oczywiście mogło być ich jeszcze więcej, ale przy trzech praktycznie nie było szyjki butelki, więc nie trzeba przesadzać.
Mądre nazewnictwo litery F / G są po prostu kontynuacją alfabetyczną po E. Przynajmniej od punktu projektowania procesora nic nie jest ze sobą powiązane.
* 1 - Wyjątek stanowi użycie ES jako miejsca docelowego łańcucha, ponieważ potrzebne są tylko dwa rejestry segmentowe. Bez nich nie byłoby to zbyt użyteczne - lub zawsze wymagałoby przedrostka segmentu. Co może zabić jedną z zaskakujących funkcji, użycie (nie powtarzających się) instrukcji łańcuchowych, skutkujące ekstremalną wydajnością ze względu na ich kodowanie jednobajtowe.
* 2 - Z perspektywy czasu „Wszystko inne Segment” byłoby o wiele lepszym nazewnictwem niż „Dodatkowy segment”.
* 3 - Zawsze ważne jest, aby pamiętać, że 8086 był pomyślany tylko jako środek zatrzymania przerwy do czasu ukończenia 8800 i był przeznaczony głównie dla świata wbudowanego, aby zatrzymać klientów 8080/85 na pokładzie.
źródło