Politechnika Częstochowska w Częstochowie
Wydział Inżynierii Mechanicznej i Informatyki
Architektura komputerów
Segmentacja pamięci wirtualnej
MSU- Semestr III
Gładysz Marek
Nowak Grzegorz
Segmentacja Pamięci Wirtualnej
Dziedzictwo po architekturze x86 wspiera mechanizm translacji - segmentu, który umożliwia oprogramowaniu systemowemu przemieszczać i izolować instrukcje i dane gdziekolwiek w przestrzeni pamięci wirtualnej. Segment znajduję w ciągłym bloku pamięci w przestrzeni adresów liniowych.
Rozmiar i umieszczenie segmentu w przestrzeni adresów liniowych jest przypadkowa.
Polecenia i dane mogą być przypisane do jednego lub kilku segmentów pamięci., każdy z jego własną charakterystyką ochrony.
Procesor wymusza zasady dyktowania jednemu segmentowi mającemu dostęp do innego segmentu.
Mechanizm segmentacji dostarcza dziesięć rejestrów segmentowych, każdy z nich definiuje pojedynczy segment. Sześć z tych rejestrów (CS, DS., ES, FS, GS, I SS) definiuje segmenty użytkownika.
Segmenty użytkownika zawierają oprogramowanie, dane, i stos i mogą być użyte, przez zarówno zastawania programowe i oprogramowanie systemowe. W przypomnieniu cztery rejestry segmentowego (GDT, LDT, IDT, i TR) definiują segmenty systemowe.
Segmenty systemowe zawierają inicjalizowane struktury danych i używane tylko przez oprogramowanie systemowe.
Rejestry segmentowe, ograniczenie definiowania rozmiaru segmentu, i definiowania atrybutów charakterystyki ochrony segmentu.
Jednakże segmentowanie jest ważną sprawą dla wszechstronności w przemieszczaniu i ochronie danych i oprogramowania, jest to często bardziej znaczące dla przechwycenia izolacji pamięci i przemieszczenia z kombinacją oprogramowania i sprzętu dla wsparcia stronicowania. Dlatego, najbardziej nowoczesne oprogramowanie systemowe opływa w wyposażenie segmentowania.
Jednakże, segmentacja nie może być kompletnie uniemożliwiona, a zrozumienie mechanizmów segmentacji jest ważne do implementacji oprogramowania systemowego w trybie długim (long-mode).
W trybie długim (long mode), efekty segmentacji zależą od tego, czy pracuje procesor w trybie kompatybilnym lub w trybie 64 bitowym:
• W trybie kompatybilności, funkcje segmentowania są to właśnie te wykonywane w trybie dziedzicznym, używając spuścizny 16 bitowej lub 32 bitowego w semantycznym trybie chronionym.
• 64 bitowy tryb, segmentowanie uniemożliwione, tworzenie płaskiej przestrzeni 64 bitowej wirtualnych adresów
Jak jest to uwidocznione, funkcje oczywiste jakichkolwiek rejestrów segmentowych, szczególnie rejestrów segmentowych systemu, ciągle używane są w trybie 64 bitowym
Segmentowanie Trybu Rzeczywistego
Po zresetowaniu lub włączeniu zasilania, procesor zawsze na początek wprowadza się w tryb rzeczywisty.
Ustawienia Chronione są wprowadzane z trybu rzeczywistego.
Tryb rzeczywisty (rzeczywisty tryb adresowania), umieszczony jest w pamięci fizycznej 1-go Mbyte.
W tym trybie, 20 adresy fizyczne są ustawiane przez przesunięcie 16 bitowych wybierających segmentów do czterech lewych bitów i dodając 16 bitowe adresy skuteczne.
Każdy 64 K segment (CS, DS., ES, FS, GS, SS) jest ustawiony w granicach 16 bajtowych.
Baza segmentu jest mniejszymi adresami w danym segmencie. i równa się segmentowi wybiórczemu * 16. Instrukcje POP i MOV mogą być użyte do ładowania (możliwie) nowych segmentów wybierających w jeden z rejestrów segmentowych. Gdy się to wykona, przełącznik jest uaktualniany i przełącznik bazy jest ustawiany do przełącznik * 16. Granica segmentu i atrybuty segmentu pozostają nie zmienione, ale są zwykle 64K (maksimum granicy możliwej) i odczyt/ zapis danych, odpowiednio.
Na dalekich przesyłach, DC (Code Segment) przełącznik jest uaktualniany do nowej wartości, i podstawa segmentu CS jest ustawiana do przełącznik * 16.
Granica segmentu CS i atrybuty pozostają bez zmian, odpowiednio, zazwyczaj 64K i odczyt / zapis.
Jeżeli tabela opisu przerwań (IDT) jest użyta do znalezienia trybu rzeczywistego IDT.
Gdt, ldt, I TSS nie są użyte do trybu rzeczywistego
Tryb Segmentacji Wirtualnej -8086.
Tryb Wirtualny- 8086 wspiera 16 bitowe uruchamianie programów w trybie 16 bitowym i w trybie chronionym. Używana jest forma prosta segmentacji pamięci, stronicowania opcjonalnego, i sprawdzania ograniczonej ochrony. Uruchamiane programy w trybie wirtualnym 8086 mogą mieć dostęp do 1MB przestrzeni pamięci.
Jako z segmentacji trybu rzeczywistego, każdy segment 64K (CS, DS., ES, FS, GS, SS) znajduje się w granicach 16 bajtów.
Baza segmentu jest w niższej przestrzeni adresów w danym segmencie, i równa się przełącznikowi segmentu * 16.
Instrukcje POP i MOV pracują dokładnie jak w trybie rzeczywistym i mogą być użyte do ładowania (możliwie) nowych przełączników segmentów w jeden z rejestrów segmentowych. Gdy jeszcze to wykona, przełącznik jest uaktualniany i baza przełącznika jest ustawiana na przełącznik * 16. Granica segmentu i atrybuty segmentu pozostają nie zmienione, ale zwykle są 64K (maxymalma możliwa granica) odpowiednio odczyt / zapis.
W dalekich transferach, przełącznik - rejestr CS uaktualniany jest do nowej wartości i podstawowy segment CS ustawiony jest do wartości przełącznik * 16. Granica segmentu CS i jego atrybuty pozostają nie zmienione, ale zwykle wynoszą 64K i odpowiednio są ustawione odczyt/ zapis.
Tabela opisująca przerwania IDT jest używana do odnalezienia Trybu rzeczywistego.
Tryb segmentacji wirtualnej 8086.
Tryb wirtualny-8086 wspiera 16 bitowe uruchamianie programów trybu rzeczywistego w trybie chronionym (zobacz poniżej). Używana jest prosta forma segmentacji pamięci, opcjonalne stronicowanie, i sprawdzanie ograniczonej ochrony.
Programy uruchomione w trybie wirtualnym 8086 mogą mieć dostęp do przestrzeni pamięci powyżej 1MB.
Tak jak segmentacja w trybie rzeczywistym, każdy segment 64K (CS, DS, ES, FS, GS, SS) ustawiany jest w granicach 16 bajtów.
Podstawowa segmentu mieści się w adresach najniższych w danym segmencie, i jest równa przełącznik segmentu * 16.
Instrukcje POP i MOV pracują dokładnie tak jak w trybie rzeczywistym i mogą być używane do ładowania (możliwe) nowy przełącznik segmentów w jeden z rejestrów segmentowych. Gdy się to zdarzy, przełącznik zostaje uaktualniony i baza przełącznika ustawiana jest (przełącznik * 16).
Granica segmentu i jego atrybutu pozostają niezmienione, ale zwykle wynosi 64K i odpowiednio odczyt / zapis.
Przerwania i wyjątki przełączają procesor do trybu chronionego.
1.3. Modele segmentacji pamięci w trybie chronionym.
Oprogramowanie systemowe może używać mechanizmu segmentacji do wspierania jednego z dwóch podstawowych modeli segmentowanej pamięci. Model pamięci płaskiej lub wielo segmentowy model.
Modele tych segmentacji są wspieranie w trybie pierwotnym i w trybie kompatybilności.
W modelu pamięci wielo segmentowej, każdy rejestr segmentowy może odnieść się do unikalnych adresów bazy z niepowtarzalnym rozmiarem segmentu. Segmenty mogą być takie małe jak pojedynczy bajt lub tak duże jak 4 Gbajtów. Gdy użyte zostało tłumaczenie strony, wiele rodzajów segmentów może być odwzorowanych na pojedynczej stronie i wiele rodzajów stron może być odwzorowanych w pojedynczym segmencie.
Rys. 1.1. przedstawia przykład modelu wielo segmentowego. Wielo segmentowy model pamięci pokazuje najlepszy poziom wszechstronności użycia oprogramowania systemowego i mechanizmu segmentacji.
Tryb odpowiadający pozwala modelowi wielo segmentowemu wspierać wcześniejsze oprogramowanie.
Jednakże w trybie odpowiadającym model pamięci wielo segmentowej jest ograniczony do 4 Gbajtów przestrzeni pamięci wirtualnej.
Dostęp do pamięci wirtualnej ponad 4 Gbajtów wymaga użycia trybu 64-bitowego, który nie wspiera segmentacji.
1.3.2. Model pamięci płaskiej.
Model pamięci płaskiej jest najprostszą formą segmentacji do wprowadzenia.
Chociaż segmentacja nie może być wyłączona. Model pamięci płaskiej umożliwia oprogramowaniu systemowemu ominąć większość mechanizmów segmentacji. W modelu pamięci płaskiej, wszystkie bazowe segmenty adresów mają wartość O, i ograniczenia segmentów ustawione są na 4 Gbajtów.
Wyczyszczając wartość segmentu bazy na 0, efektywnie uniemożliwiając translacje segmentu, wynikającego w pojednynczym segmencie, o rozpiętości całego wejścia przestrzeni adresów wirtualnych.
Wszystkie odnośniki do tego pojedynczego płaskiego segmentu. Rysunek 1-2 przedstawia przykład modelu płaskiej pamięci.
1.3.3. Segmentacja w trybie 64 bitowym.
W trybie 64 bitowym, uniemożliwiona jest segmentacja. Wartość podstawy segmentu jest ignorowana i traktowana jako 0 przez sprzęt segmentujący.
Podobnie, ignorowane są granice segmentu i większość atrybutów. Jest kilka wyjątków, segment CS DPL,
atrybuty D i L używane są (odpowiednio) do ustanowienia poziomu uprzywilejowania dla programu,
przykładowy rozmiar operatora, a także czy program jest uruchomiony w trybie 64 bitowym lub w trybie
kompatybilnym.
Segmenty FS i GS mogą być używane jako dodatkowe podstawowe rejestry w obliczeniach
adresów, i segmenty te mogą mieć wartości podstawowych adresów nie-zerowe.
To udogodnienia adresowania lokalnych - szeregowych danych i pewnych struktur danych oprogramowania
Systemowego. Popatrz na rejestry FS I GS w trybie 64 bitowym. Systemowe rejestry segmentowe używane są
zawsze w trybie 64 bitowym.
Segmentacja struktur danych i rejestrów.
Rys. 4.1 przedstawia następujące struktury danych używanych przez mechanizm segmentacji:
• Deskryptor segmentów - Jak sama nazwa sugeruje, Deskryptory segmentów opisują segment, zawierając jego położenie w wirtualnej przestrzeni adresów, jego rozmiar, charakterystyki ochrony i inne atrybuty.
• Deskryptor Segment Tabel Deskryptory przechowywane są w pamięci w jednej z trzech tabel. Tabela deskryptora globalnego (GDT) przechowuje deskryptory segmentu które mogą być dzielone między wszystkimi zdarzeniami. Wiele tabel deskryptorów lokalnych (LDT) mogą być definiowane do przechowywania deskryptorów, które są używane do wyjątkowych zdarzeń, i normalnie są współdzielone globalnie. Tabela deskryptor przerwań (IDT) przechowuje deskryptory bramy, które są używane do dostępu do segmentów, gdy posiadacze przerwania są umieszczone.
• Segment Stanu Zdarzenia - Segment Stanu Zdarzenia (TSS) jest specjalnym typem segmentu systemowego, który zawiera informacje stanu - zdarzenia i struktury danych dla każdego zdarzenia. Na przykład, TSS przechowuje kopie GPR-ów i rejestru EFLAGS, gdy zdarzenie jest zawieszone. TSS również przechowuje do stosów uprzywilejowanych programowo. TSS i mechanizm przełącznika - zdarzeń opisane są w rozdziale "Zarządzanie zdarzeniami"
• Deskryptory Przełączniki Segmentu są wybierane do użycia z tabel deskryptora używając przełącznika segmentu. Przełącznik segmentu zawiera indeks zarówno w GDT lub LDT. IDT jest indeksowany za pomocą wektora przerwań, jak zostało to opisane "Wcześniejszy tryb chroniony kontroli przepływów przerwań).
Rys. 1.1. Struktury segmentacji danych.
Rys. 1.2 przedstawia rejestry używane przez mechanizm segmentacji. Rejestry posiadają następujący stosunek do struktur danych:
• Rejestry segmentowe - Sześć rejestrów segmentowych (CS, DS., ES, FS, GS i SS) używane są do wskazania segmentów użytkownika. Przełącznik segmentu wybiera deskryptor , gdy ładowany jest w jeden z rejestrów segmentowych. Powoduje to, że procesor automatycznie ładuje wybrany deskryptor w część rejestru segmentowego programowo niewidoczną.
• Rejestry deskryptora tabeli - Trzy rejestry deskryptora tabeli (GDTR, LDTR, i IDTR) używane są do wskazania segmentów systemowych. Rejestry deskryptory tabeli identyfikują położenie pamięci wirtualnej i rozmiar deskryptorów tabel.
• Rejestr zdarzenia (TR) - opisuje położenie i granice obecnego segmentu stanu zdarzenia (TSS).
Rysunek 1.2. Rejestry tabel deskryptorów i segmentów
Czwarty jejestr segment systemowy, TR wskazuje TSS. Struktura danych i rejestry połączone są segmentami stanu zdarzenia opisanych w (Podstawy zarządzania zdarzeniami)
1.5. Przełączniki segmentu i rejestry.
1.5.1. Przełączniki segmentu.
Przełączniki segmentu są wskaźnikami do specyficznych wejść w tabelach globalnych i lokalnych deskryptorów.
Rys. 1.3 przedstawia format przełącznika segmentu.
BITY |
SYMBOLE |
OPIS |
R/W |
15-3 |
SI |
Przełącznik indeksu |
R/W |
2 |
TI |
Wskaźnik tabeli |
R/W |
1-0 |
RPL |
Wywoływacz poziomu uprzywilejowania |
R/W |
Przełącznik formatu zawiera następujące pola:
Przełącznik indeksu pola. Bity 15-3. Przełącznik indeks pola opisuje wejście w tabeli deskryptora. Wejścia tabeli deskryptora są długości 8 bajtów, więc indeks przełącznika jest skalowany przez 8 do formy przesunięcia bajtowego w tabeli deskryptora. Przesunięcie jest więc dodawane do zarówno globalnej lub lokalnej tabeli deskryptora adresów podstawowych (tak jak zostało wskazane przez bit indeksu tabeli) do formy adresów wejścia deskryptora w przestrzeni adresów wirtualnych.
Niektóre wejścia deskryptorów w trybie długim są długie na 16 bajtów częściej niż 8 bajtowe ( Spójrz na " Wcześniejsze deskryptory segmentów" aby dowiedzieć się więcej na temat wejść tabeli deskryptora w trybie długim). Te rozszerzone deskryptory pobierają dwa wejścia w tabeli deskryptora. Tryb długi, jednakże, kontynuując skalowanie indeksu przełącznika przez osiem do formy przesunięcia tabeli deskryptora.
Oprogramowanie systemowe jest odpowiedzialne za łączenie przełączników takich które prawidłowo wskazują początek rozszerzonego wejścia.
Bit wskaźnik tabeli (TI). 2 bit . Bit TI wskazuje która tabela przechowuje deskryptor odnoszący się do indeksu przełącznika. Gdy TI=0 używany jest GDT, a gdy TI=1 używany jest LDT. Adresy bazowe tabeli deskryptora są czytane z odpowiedniego tabeli deskryptora i dodawane są od indeksu skalowanego tak jak zostało to opisane wcześniej.
Pole wywoływania poziomu przywileju. Bity 1-0 RPL reprezentuje poziom przywileju. (CPL). Procesor operuje w czasie tworzenia przełącznika.
RPL używany jest w sprawdzaniu przywileju segmentu by zapobiec uruchomieniu oprogramowania na niższym poziomie przywileju od danych uprzywilejowanego dostępu.
Pusty przełącznik. Przełączniki puste mają indeks przełącznika 0 i TI=0, odpowiednio do pierwszego wejścia w GDT, Jednakże, puste przełącznik nie odnoszą się do pierwszego wejścia GDT, ale używane są zamiast nieodpowiednich, nieużywanych rejestrów segmentowych. Generalny wyjątek ochrony (#GP) zdarza się, jeżeli zrobione jest odniesienie do rejestru segmentowego zawierającego pusty przełącznik. Przez zainicjalizowanie nieużywanych rejestrów segmentowych z oprogramowaniem pustych przełączników, może wpaść w pułapkę odnosząc się do nieużywanych segmentów.
Przełączniki puste mogą tylko być ładowane w rejestry segmentów danych DS., ES, FS, i GS, i w rejestr deskryptora tabeli LDTR. #GP zdarza się, jeżeli oprogramowanie próbuje ładować z przełącznikami pustymi rejestry CS lub SS.
1.5.2. Rejestry segmentowe
Sześć 16 bitowych rejestrów segmentowych są przeznaczone do odnoszenia się do sześciu segmentów w jednakowym czasie. Wszystkie zdarzenia programowe wymagają aby przełączniki segmentów były ładowane do rejestrów CS i SS. Użycie segmentów DS., ES, FS i GS jest opcjonalne, ale w pobliżu całego oprogramowania dostępu danych i dlatego wymagany jest przełącznik w rejestrze DS. Tabela 1-1 wymienia wspierane rejestry segmentowe i ich funkcje.
Rejestr Segmentowy |
Funkcje Rejestru segmentowego |
CS |
Odnosi się do wejścia deskryptora segmentu kodu |
DS |
Odnosi się do przykładowego wejścia deskryptora segmentu danych |
ES |
Odnosi się do opcjonalnego wejścia deskryptora segmentu danych |
FS |
Odnosi się do opcjonalnego wejścia deskryptora segmentu danych |
GS |
Odnosi się do opcjonalnego wejścia deskryptora segmentu danych |
SS |
Odnosi się do wejścia deskryptora segmentu stosu |
Procesor utrzymuje ukrytą część rejestru segmentowego i dodatku wartość przełącznika ładowanego przez oprogramowanie.
Ta ukryta część zawiera znalezione wartości w wejściu tabeli deskryptora odnoszącego się przez przełącznik segmentu. Procesor ładuje wejście tabeli deskryptora w ukrytą część, gdy rejestr segmentowy jest ładowany.
Przez utrzymywanie odpowiedniego wejścia tabeli deskryptora w sprzęcie, przekształcenie jest optymalizowane dla większości odniesień do pamięci.
Rys. 1-4 przedstawia format widocznych i ukrytych części rejestru segmentowego. Z wyjątkiem segmentu FS i segmentu bazowego GS, oprogramowanie nie może bezpośrednio czytać lub zapisywać w ukrytej części. ( Pokazana jako zacieniowane na szaro na rys. 1-4)
Rys. 1-4. Format rejestru segmentowego
Rejestr CS . Rejestr CS ładowany jest z przełącznikiem segmentu w odniesieniu do obecnego wejścia deskryptora segmentu kodu. Wszystkie instrukcje przenoszą odniesienie do deskryptora CS. Gdy nowy przełącznik jest ładowany w rejestr CS, obecny poziom przywileju (CPL) procesora ustawiany jest do tego poziomu przywileju deskryptora (DPL) segmentu CS.
Rejestry segmentu danych. Rejestr DS. ładowany jest z przełącznikiem segmentu odnoszącego się do przykładowego wejścia deskryptora segmentu danych.
Rejestr SS ładowany jest z przełącznikiem segmentu stosu. Rejestry ES, FS i GS są ładowane opcjonalnie z przełącznikami segmentu odnoszących się do innych segmentów danych.
Przykładowe dostępy do danych odnoszą się do deskryptora DS. za wyjątkiem dwóch następujących spraw:
• Deskryptor DS. jest odniesiony do przeznaczeń instrukcji łańcuchowych.
• Deskryptor SS jest odniesiony do operacji stosu.
Rejestr CS w trybie 64 bitowym. W trybie 64 bitowym , większość ukrytych części rejestru CS jest ignorowana. Tylko takie atrybuty są rozpoznawane w trybie 64 bitowym L (Long- długi), i D (default - przykładowy rozmiar operacji), i DPL ( deskryptor poziomu uprzywilejowania) .
Obliczenia adresów przybiera wartość bazową CS jako 0. Odniesienia CS nie sprawdzają wartości granicy CS, ale zamiast tego sprawdzają adresy efektywne w postaci kanonicznej.
Rejestry DS., ES, SS, w trybie 64 bitowym. W trybie 64 bitowym, zawartość rejestrów segmentowych ES, DS., i SS jest ignorowana. Wszystkie pola (baza, granica, i atrybuty) w ukrytej części rejestru segmentowego są ignorowane.
Obliczenie adresów w trybie 64 bitowym odnoszących się do segmentów ES, DS., lub SS są traktowane jako jeżeli baza segmentu jest 0. Zamiast przekształcania sprawdzania granicy, procesor sprawdza te wszystkie odniesienia adresów - wirtualnych które są w postaci kanonicznej.
Zarówno nie umożliwia i nie aktywuje trybu długiego lub nie przełącza pomiędzy trybem 64 bitowym i trybami kompatybilności zmieniającego zawartość widocznej i ukrytej części rejestrów segmentowych. Rejestry te pozostają niezmienione podczas wykonywania trybu 64 bitowego, chyba że przeprowadzane są wyraźne ładowania segmentu.
Rejestry GS i FS w trybie 64 bitowym. W przeciwieństwie do segmentów CS, DS., ES, i SS, przekroczenia segmentów FS i GS mogą być użyte w trybie 64 bitowym. Gdy przekroczenia segmentów FS i GS są używane w trybie 64 bitowym, ich odpowiednie adresy bazowe są używane w obliczaniu efektywnych adresów (EA). Kompletne obliczenie EA wtedy zostaje (FS lub GS).baza + baza + (skala * indeks) + przemieszczenie. Wartości baza.FS i baza.GS są również rozszerzone od pełnego 64 bitowego rozmiaru adresów - wirtualnych, tak jak przedstawiono w rysunku 1-5. Rezultat obliczenia EA jest upoważniony do narzucania się wzdłuż pozytywnych i negatywnych adresów.
Rys. 1-5 Rejestry segmentowe FS i GS - Format trybu 64 bitowego
Tryb 64 bitowy, przekroczenia segment FS i segment GS unieważnienia nie są sprawdzane dla granicy i atrybutów. Zamiast tego procesor sprawdza te wszystkie odniesienia adresów- wirtualnych które są w postaci kanonicznej.
Instrukcje ładowania rejestru segmentowego (MOV do Rej_S i POP do Rej_S) ładuje tylko 32 bitową wartość adresów bazy w ukrytej części rejestrów segmentowych FS i GS. Bity adresów bazy powyżej dolnych 32 bitów czyszczone są do 0 jako rezultat ładowania rejestru segmentowego.
Aby umożliwić ładowanie wszystkich 64 bitów bazy adresów 64 bitowych. Baza FS i baza GS ukryte pola deskryptora rejestru są mapowane do MSR-ów. Oprogramowanie uprzywilejowane (CPL=0) może ładować 64 bitową bazę adresów w bazie. FS lub w bazę GS używając pojedynczej instrukcji WRMSR. Adresy zapisywane w rozszerzonej bazie FS i w bazie GS rejestry muszą być w postaci kanonicznej. Instrukcje WRMSR , które próbują zapiać nie - kanoniczne adresy w tych rejestrach powodują zdarzenie wyjątku ochrony generalnej (#GP).
Adresy MSR Baza FS jest C000_0100h gdy adresy MSR baza GS jest C000_0101h.
Gdy w trybie kompatybilności, przeprowadza unieważnienie jak zdefiniowana została przez wcześniejszą architekturę x86 mimo wartości ładowanych w górne 32 bity ukrytego pola adresów bazy rejestru deskryptora. Tryb kompatybilności ignoruje górne 32 bity gdy wyliczane są adresy efektywne.
1.6 Tabele deskryptora
Tabele deskryptora używane są przez mechanizm segmentacji gdy umożliwiony jest tryb chroniony. (CR0.PE=1). Tabel te przechowują wejścia deskryptora które opisują położenie, rozmiar i atrybuty przywilejów segmentu. Wszystkie odnośniki do pamięci w trybie chronionym mają dostęp do wejść tabeli - deskryptora.
Jak wspomniano wcześniej są trzy typy tabel deskryptorów wspieranych przez mechanizm segmentacji x86:
• Tabela deskryptora globalnego (GDT)
• Tabela deskryptora lokalnego (LDT)
• Tabela deskryptora przerwań (IDT)
Oprogramowanie ustanawia położenie tabeli deskryptora w pamięci przez inicjalizację w odpowiadając rejestrowi tabeli deskryptora. Rejestry tabeli - deskryptora i tabele deskryptora opisane są w następujących sekcjach.
1.6.1 Oprogramowanie systemowe trybu chronionego musi tworzyć globalną tabele - deskryptora (GDT). GDT zawiera segment- kodu i wejścia deskryptora segmentu danych (segmenty użytkownika) dla segmentów które mogą być współdzielone przez wszystkie zdarzenia. W dodatku do segmentów użytkownika, GDT może również przechowywać deskryptory bramy i inne deskryptory segmentowe - systemowe. Oprogramowanie systemowe może przechowywać tabele GDT gdziekolwiek w pamięci i powinno chronić segment zawierający GDT od oprogramowania nie uprzywilejowanego.
Przełącznik segmentu wskazują tabele GDT gdy bit indeksu tabeli (TI) w przełączniku jest wyczyszczony do 0. Indeks przełącznika część segmentu przełącznika odnosi się do specyficznego wejścia w GDT.
Rys. 1-6 przedstawia jak przełącznik segmentu indeksuje w GDT. Jedną specjalną formą przełącznika segmentu jest przełącznik pusty. Przełącznik pusty wskazuje pierwsze wejście w GDT (indeks przełącznika jest 0 i TI=0). Jednakże, puste przełączniki nie odnoszą się do pamięci, więc pierwsze wejście GDT nie może być użyte do opisania segmentu. Pierwsze używalne wejście GDT odniesione jest z 1 indeksem przełącznika.
Rys. 1-6. Dostępy do Tabeli - Deskryptora Lokalnego i Globalnego
1.6.2. Rejestr tabeli deskryptora globalnego Rejestr tabeli deskryptora globalnego (GDTR) wskazuje do lokalizacji w pamięci GDT i definiuje jego rozmiar. Rejestr ten ładowany jest z pamięci przy użyciu instrukcji LGDT. Rys.1-7 przedstawia format GDTR w trybie wcześniejszym i w trybie kompatybilności.
Rys. 1.7 Tryby wcześniejsze - Format GDTR i IDTR.
Rys. 1-8 przedstawia format GDTR w trybie 64 bitowym
Rys. 1-8 Tryb długi -Format GDTR i IDTR.
GDTR zawiera 2 pola:
Granica. 2 bajtów. Bity te definiują 16 bitową granicę, lub rozmiar, GDT w bajtach. Wartość granicy dodawana jest do adresów bazy zyskując zakończenie bajtu adresów GDT. Wyjątek ochrony generalnej (#GP) zdarza się jeżeli oprogramowanie próbuje udostępnić granice GDT poza deskryptor.
Przesunięcie w tabelach deskryptora nie są rozszerzone przez architekturę x86-64 wspierającą tryb długi. Dlatego, rozmiar pola granicy LDTR jest niezmieniony od rozmiaru dziedzicznego.
Procesor nie sprawdza granicy LDT i długości trybu długiego podczas dostępu do LDT.
Atrybuty. Pole to przechowuje atrybuty deskryptora, takie jak prawa przywileju, obecność segmentu i ziarnistości segmentu .
1.6.5 Tabela deskryptora przerwań.
Ostatecznym typem tabeli deskryptora jest tabela deskryptor przerwań (IDT) Wiele tabel IDT może być utrzymywanych przez oprogramowanie systemowe. Oprogramowanie systemowe wybiera odpowiednie IDT przez załadowanie rejestru tabeli deskryptora przerwań (IDTR) ze wskaźnikiem do IDT. Tak jak GDT i LDT, oprogramowanie systemowe może przechowywać IDT gdziekolwiek w pamięci i powinno chronić zawartości IDT od oprogramowania nie uprzywilejowanego.
IDT może zawierać tylko następujące typy deskryptorów bram:
• Bramy przerwań,
• Bramy pułapek,
• Bramy zdarzeń.
Użycie deskryptorów bram przez mechanizm przerwań opisany jest w temacie "Wyjątki i przerwania|"
Generalny wyjątek ochrony (#GP) zdarza się, jeżeli deskryptor IDT odnosi się przez przerwanie lub wyjątek, który nie jest tego typu co wymienione powyżej.
Wejścia IDT wybierane są używając numeru wektora przerwań raczej niż wartości przełącznika. Numer wektora przerwań skalowany jest przez rozmiar wejścia deskryptora przerwań do formy przesunięcia w IDT.
Rozmiar wejścia deskryptora przerwań zależy od trybu operacji procesora w następujący sposób:
• W trybie długim, wejścia tabeli deskryptora są 16 bitowe.
• W trybie wcześniejszym, wejścia tabeli deskryptora przerwań są 8 bitowe.
Rys. 1-12 przedstawia jak indeksuje IDT numer wektora przerwań.
Rys. 1-12 Indeksacja IDT
1.6.6 Rejestr tabeli - deskryptora przerwań
Rejestr tabeli - deskryptora przerwań (IDTR) wskazuje w pamięci IDT i definiuje jego rozmiar. Rejestr jest ładowany z pamięci przy użyciu poleceń LIDT) Format IDTR jest taki sam jak GDTR we wszystkich trybach. Rys. 1-7 przedstawia format IDTR w trybie wcześniejszym. Rys. 1-8 przedstawia format IDTR w trybie długim.
Przesunięcia w tabelach deskryptorach nie są rozszerzone o wspieranie trybu długiego przez architekturę x86-64. Dlatego, rozmiar pola-granicy jest niezmieniony od wcześniejszego rozmiaru. Procesor nie sprawdza granicy IDT w trybie długim podczas dostępu do IDT.
1.7. Wcześniejsze deskryptory segmentu
1.7.1. Format deskryptora.
Definicja deskryptora segmentu, chroni i oddziela segmentu każdy od każdego. Są dwa podstawowe typu deskryptorów, każde które są używane do opisu różnych typów segmentów (lub bram):
• Segmenty użytkownika - Zawierają segmenty kodu i segmenty danych. Segmenty stosu są typem segmentu danych.
• Segmenty systemowe - Segmenty systemowe zawierają segmenty LDT i segmenty stanu zdarzenia (TSS). Deskryptory bramy są innego typu deskryptor segmentu - systemowego. Raczej niż segmenty opisowe, deskryptory bramy wskazują na punkty wejścia programu.
Rys. 1-13 przedstawia ogólny format segmentu użytkownika i deskryptory segmentu systemowego. Segmenty systemowe i użytkownika są rozróżniane przy użyciu bitu S. S=1 wskazuje segment użytkownika, a S=0 wskazuje segment systemu. Szare tło wskazuje zarezerwowane pole lub bit Format dala deskryptora bramy różni się od ogólnego deskryptora segmentowego, i opisane jest w rozdziale "Deskryptory bramy"
1-13 Tryb wcześniejszego - deskryptora segmentu ogólnego
Rys. 1-13 przedstawia pola w ogólnym, trybie wcześniejszym, 8 bitowy deskryptor segmentowy. Na tym rysunku, +0 zaznacza adresy deskryptorów pierwszego bajtu, a +4 wskazuje adresy deskryptorów piątego bajtu.
Pola są definiowane w następujący sposób od najmniej znaczącej do najwięcej znaczącej pozycji bitu:
Granica segmentu. 20 bitowa granica segmentu jest formowana przez zgrupowanie bitów 19-16 bajtu +4 z bitami 15-0 bajtu +0. Granica segmentu definiuje rozmiar segmentu, w bajtach. Bit kontrolny Granulowatości (ziarnistości) (G) określa jak pole granicy segmentu jest skalowane. Dla segmentów danych, rozszerzone w dół bit (E) ustala czy grania segmentu definicje są w dolne lub górne ograniczenie segmentu.
(Bit E Rozszerzenia w dół lub w górę)
Jeżeli oprogramowanie odnosi się do deskryptora segmentu z adresami poza granice segmentu, zdarzy się wyjątek ochrony generalnej (#GP). (#GP) zdarzy się jeżeli jakaś część odniesienia pamięci pada na zewnątrz granicy segmentu. Na przykład, odniesienie adresów podwójnym słowem (4 bajtowym) spowoduje #GP, jeżeli jeden lub więcej bajtów usytuowanych jest poza granicą segmentu.
Adresy bazowe. 32 bitowe adresy bazowe formowane są przez grupowanie bitów 31-24 bajtu +4 z bitami 7-0 bajtu +4 i z bitami 15-0 bajtu +0. Pole adresów bazowych segmentu znajduje początek segmentu w przestrzeni adresów wirtualnych.
Bit S i Pole typu. Bit 12 bajtu +4, i bity 11-8 bajtu +4. Bit S i Pola typu, razem wyszczególniają typ deskryptora i jego charakterystyki dostępu. Tabela 1-2 podsumowuje typu deskryptorów przez rozkodowanie pola S i podaniu bezpośredniego odniesienia do wyjaśnienia Pola-typu
Typy deskryptorów
Pole S |
Typ deskryptora |
Wyjaśnienie typu pola |
(system) 0 |
LDT |
Spójrz na tabele 1-5 |
|
TSS |
|
|
Brama |
|
(użytkownik) 1 |
Kod |
Spójrz na tabele 1-3 |
|
Dane |
Spójrz na tabele 1-4 |
Deskryptor poziomu- uprzywilejowania Pole (DTL). Bity 14-13 bajtu +4. Pole DPL wskazuje poziom przywileju deskryptora segmentu. DPL może być ustawione w każdej wartości od 0 do 3, z 0 wyszczególniając większy przywilej i 3 mniejszy przywilej.
Obecny bit (P). Bit 15 bajtu +4. Bit obecny - segment wskazuje że segment jest odniesiony przez załadowany w pamięci deskryptor . Jeżeli zrobione jest odniesienie do wejścia deskryptora, gdy P=0, zdarzy się wyjątek nieobecnego segmentu (#NP.). Bit ten jest ustawiany i czyszczony przez oprogramowanie systemowe i nigdy nie zmieniany przez procesor.
Dostępne dla oprogramowania. Bit (AVL) Bit 20 bajtu +4. Pole to dostępne jest dla oprogramowania, które może zapisywać każdą wartość do tego pola. Procesor nie ustawia i nie czyści tego pola.
Przykładowy rozmiar operatora Bit (D/B). Bit 22 bajtu +4. Przykładowy bit rozmiaru operatora znajduje się deskryptorach segmentu kodu i segmentu danych, ale nie znajduje się w deskryptorach segmentów systemowych.
Ustawienie tego bitu na 1 wskazuje przykładowy 32 bitowy rozmiar operatora, a czyszcząc go do 0 wskazuje 16 bitowy przykładowy rozmiar. Bit ten ma wpływ na zależności segmentu na typach deskryptorów segmentów. Spójrz na ("Bit (D) Przykładowy rozmiar operatora segmentu - kodu)
Granulowatość (ziarnistość) Bit (G) . Bit 23 bajtu +4. Bit granulowatości (ziarnistości) wyszczególnia jak skalowane jest pole granicy - segmentu. Czyszcząc bit G do 0 wskazuje, że nie skalowana jest granica pola. W tym przypadku, granica równa się ilości bajtów dostępnych w segmencie. Ustawienie bitu G na 1 wskazuje, że skalowana jest przez 4 Kbajty granica pola (4096 bajtów). Tu, granica pola równa się numerowi 4Kbajtowych bloków dostępnych w segmencie.
Ustawienie granicy na 0 wskazuje 1 bajtową granice segmentu gdy G=0.
Ustawienie takiego samej granicy na 0 gdy G=1 wskazuje granice segmentu na 4095
Bity zarezerwowane. Ogólnie, oprogramowanie powinno czyścić wszystkie zarezerwowane bity na 0, więc mogą one być definiowane w przyszłych zmianach architektury x86-64
1.7.2. Rys. 1-14 pokazuje format deskryptora segmentu - kodu. (cieniowane na szaro wskazują na zarezerwowany bit) Wszystkie zdarzenia programowe wymagają aby przełącznik segmentu, odnoszącego się do odpowiednich deskryptorów segmentów kodu, który ładowany jest do rejestru CS. Segmenty kodu ustanawiają tryb operacji procesora i wykonanie poziomu-przywileju. Ogólnie segmenty zawierają tylko instrukcje i tylko do wykonywania, lub wykonywanie i tylko do odczytu. Oprogramowanie nie może zapisać w segment którego przełącznik odnosi się do deskryptora segmentu - kodu.
Rys. 1-14 Tryb wcześniejszego- deskryptora segmentu - kodu
Deskryptory segmentu kodu posiadają bit S ustawiony na 1, identyfikujący segmenty jako segmenty użytkownika.
Pole typu bit 11 rozróżnia deskryptory segmentu - kodu (bit 11 ustawiony na 1), od deskryptorów segmentów danych (bit 11 wyczyszczony jest do 0). Przypominanie typu-pola bity (10-8) definiują charakterystyki dostępu do segmentu kodu, w następujący sposób:
Dostosowani Bit (C). Bit 10 bajtu +4. Ustawienie tego bitu na 1 identyfikuje segment kodu jako dostosowany.
Gdy sterowanie jest transferowane do wyższego- przywileju dostosowania segmentu kodu (C=1) z wyższego poziomu uprzywilejowania niż CPL może zdarzyć tylko przez deskryptory bramy.
Odczytywany Bit (R ) Bit 9 bajtu +4. Ustawienie tego bitu do 1 wskazuje segmentowi kodu, że jest wykonywalny i odczytywalny jako dane. Gdy bit ten jest czyszczony do 0 , segment kodu jest wykonywany, ale próbuje czytać dane z segmentu kodu powodując zdarzenie generalnego wyjątku ochrony (#GP).
Dostępności Bit (A) Bit 8 bajtu +4 . Dostępny bit ustawiony jest na 1 przez procesor gdy deskryptor kopiowany jest z GDT lub LDT w rejestr CS. Bit ten czyszczony jest tylko przez oprogramowanie.
Tabela 1-3 podsumowuje segment kodu przetworzenia pola-typu.
Tabela 1-3 Typy deskryptora segmentu - kodu
Wartość Hex |
Pole typu |
Opis |
|||
|
Bit 11 (Kod / dane) |
Bit 10 |
Bit 9 |
Bit 8 |
|
|
|
Dopasowanie (C)d |
Do odczytu (R ) |
Dostępny (A) |
|
8 |
1 |
0 |
0 |
0 |
Tylko do wykonywania |
9 |
|
0 |
0 |
1 |
Tylko do wykonywania - dostępne |
A |
|
0 |
1 |
0 |
Do wykonywania / odczytu |
B |
|
0 |
1 |
1 |
Do wykonywania / odczytu - dostępne |
C |
|
1 |
0 |
0 |
Dostosowane, tylko do odczytu |
D |
|
1 |
0 |
1 |
Dostosowane, tylko do odczytu - dostępne |
E |
|
1 |
1 |
0 |
Dostosowane, Do wykonania / Odczytu |
F |
|
1 |
1 |
1 |
Dostosowane, Do wykonania / Odczytu - Dostępne
|
Rozmiar przykładowego operatora segmentu kodu Bit (D) Bit 22 bajtu +4. W deskryptorach segmentu - kodu, bit D wybiera przykładowy rozmiar operatora i rozmiary adresów. W trybie , gdy D=0 przykładowy rozmiar operatora i rozmiary adresów są 16 bitowe i gdy D=1 rozmiar przykładowego operatora i rozmiar adresów jest 32 bitowy. Prefiksy instrukcji mogą być używane do przekroczenia rozmiaru operatora lub rozmiaru adresów lub obydwóch.
1.7.3. Deskryptory segmentu danych.
Rys. 1-15 przedstawia format deskryptora segmentu danych.
Segmenty danych zawierają nie wykonywalne informacje i mogą być dostępne jako tylko do odczytu lub odczytu zapisu. Odniesione są używając rejestrów segmentów danych DS., ES, FS, GS lub SS. Rejestr segmentu danych DS. przechowuje przełącznik segmentu dla przykładowego segmentu danych. Rejestry segmentowe danych ES, FS, i GS przechowują przełączniki segmentów do dodatkowych używanych segmentów danych przez obecne zdarzenia programowe.
Rejestr segmentu stosu jest specjalną formą rejestru segmentu danych. Jest odniesiony używając rejestru segmentowego SS i musi być typu odczyt/ zapis. Gdy ładuje się rejestr SS, procesor wymaga by pasował o
odnośnik przełącznika , deskryptor segmentu danych możliwy do zapisu.
Rys. 1-15 Deskryptor segmentu danych - Tryb dzidziczny
Deskryptory segmentów danych mają bit S ustawiony na 1, idnentyfikując je jako segmenty użytkownika. Typ pola bit 11 rozróżnia deskryptory segmentów danych (bit 11 wyczyszczony do 0) z deskrtyptoów segmentu kodu (bit 11 ustawiony na 1). Przypomnienie Typu-pola bity (10-8) definiują charakterystyki dostępów do segmentów danych, w następujący sposób:
Rozszerzenie w dół bit B. Bit 10 bajtu +4 . Ustawienie tego bitu na 1 identyfikuje segment danych jako rozszerzony w dół. W rozszerzonych w dół segmentach, granica segmentu definiuje ograniczenia mniejszego segmentu gdy baza jest w górnym ograniczeniu. Pasujący segment przesuwa się w segmenty rozszerzone w dół leżące w zakresie granica + 1 do FFFFh lub FFFF_FFFFh, w zależności od wartości segmentu danych przykładowy rozmiar operatora bit (D/B).
Segmenty rozszerzone w dół są użyteczne dla stosów, które rosną w kierunku dolnym i jako elementy są przesuwane na stos. Wskaźnik stosu , ESP, jest zmniejszany przez wielkość równą rozmiarowi operatora jako rezultat wykonania instrukcji PUSH.
Wyczyszczenie bit E do 0 identyfikuje segment danych jako rozszerzony w górę. Pasujący segment przesuwa segmenty rozszerzone w górę leżących w bajcie w zakresie od 0 do granicy segmentu.
Bit (W) do zapisu. Bit 9 bajtu +4. Ustawienie tego bitu na 1 identyfikuje segment danych jako odczyt/zapis.
Gdy bit ten czyszczony jest do 0, segment jest ustawiony tylko do odczytu. Generalny wyjątek ochrony (#GP) zdarzy się jeżeli oprogramowanie próbuje zapisać segment danych gdy W=0.
Bit (A) dostępu. Bit 8 bajtu +4. Bit dostępu ustawiony jest na 1 przrez procesor gdy deskryptor kopiowany jest z GDT lub LDT w jeden z rejestrów segmentu danych lub rejestr segmentu stosu. Bit ten czyszony jest tylko przez oprogramowanie.
Tabela 1-4 Typy deskryptora segmentu - kodu
Wartość Hex |
Pole typu |
Opis |
|||
|
Bit 11 (Kod / dane) |
Bit 10 |
Bit 9 |
Bit 8 |
|
|
|
Dopasowanie (C)d |
Do odczytu (R ) |
Dostępny (A) |
|
0 |
0 |
0 |
0 |
0 |
Tylko do wykonywania |
1 |
|
0 |
0 |
1 |
Tylko do wykonywania - dostępne |
2 |
|
0 |
1 |
0 |
Do wykonywania / odczytu |
3 |
|
0 |
1 |
1 |
Do wykonywania / odczytu - dostępne |
4 |
|
1 |
0 |
0 |
Dostosowane, tylko do odczytu |
5 |
|
1 |
0 |
1 |
Dostosowane, tylko do odczytu - dostępne |
6 |
|
1 |
1 |
0 |
Dostosowane, Do wykonania / Odczytu |
7 |
|
1 |
1 |
1 |
Dostosowane, Do wykonania / Odczytu - Dostępne
|
Segment danych Przykładowy rozmiar operatora Bit (D/B). Bit 22 bajtu +4 . Dla rozszerzenia w dół segmentów danych (E=1), ustawienie D=1 ustawia górne ograniczenie segmentu przy 0_FFFF_FFFFh. Wyczyszczenie D=0 ustawia górne ograniczenie segmentu 0_FFFFh.
W przypadku gdy segment danych odnosi się do przełącznika stosu (SS), Bit D odniesiony jako bit B. Dla segmentów stosu, Bit B ustawia przykładowy rozmiar stosu. Ustawienie B=1 ustanawia 32 bitowy stos odniesiony przez 32 bitowy rejestr ESP. Wyczyszczenie B=0 ustanawia 16 bitowy stos odniesiony przez 16 bitowy rejestr SP.
1.7.4. Deskryptory systemu.
Są dwa generalne typy deskryptorów systemu: deskryptory segmentu -systemu i deskryptory bramy. Deskryptory segmentu - systemu używane są do opisu segmentów LDT i TSS.
Deskryptory bramy nie opisują segmentów, ale zamiast tego przechowują wskaźniki do deskryptorów segmentu - kodu. Deskryptory bramy używane są do sterowania transferem w trybie chronionym mniej uprzywilejowanego i bardziej uprzywilejowanego oprogramowania.
Deskryptory segmentu - systemu mają bit S wyczyszczony do 0. Typ pola używany jest do rozróżnienia różnych LDT, TSS, i deskryptorów bramy jeden od drugiego
Tabela 1-5 podsumowuje przetwarzanie typu - pola segmentu systemu.
Tabela 1-5. Typy deskryptorów segmentu systemu (S=0) Tryb dziedziczny
Wartość Hex |
Typ pola (Bity 11-8) |
Opis |
0 |
0000 |
Zarezerwowane (nie legalne) |
1 |
0001 |
Dostępne 16 bitów TSS |
2 |
0010 |
LDT |
3 |
0011 |
Zajęty 16 bitowy TSS |
4 |
0100 |
Przywołanie bramy 16 bitowy |
5 |
0101 |
Zdarzenie bramy |
6 |
0110 |
Przerwanie bramy 16 bitowe |
7 |
0111 |
Pułapka bramy 16 bitowa |
8 |
1000 |
Zarezerwowane (nie legalne) |
9 |
1001 |
Dostępne 32 bitowe TSS |
A |
1010 |
Zarezerwowane (nie legalne) |
B |
1011 |
Zajęte 32 Bitowe TSS |
C |
1100 |
Przywołanie bramy 32 bitowej |
D |
1101 |
Zarezerwowane (nie legalne) |
E |
1110 |
Przerwanie bramy 32 bitowej |
F |
1111 |
Pułapka bramy 32 bitowej |
Rys 1-16 przedstawia format deskryptora segmentu systemu w trybie dziedzicznym używanego do odniesienia segmentów LDT i TSS . Format ten używany jest również w trybie kompatybilności. Segmenty systemowe używane są w następujący sposób:
• Zwykle LDT przechowuje deskryptory segmentu należące do pojedynczego zdarzenia.
• TSS jest strukturą danych do przechowywania informacji o stanie procesora. Stan procesora jest zapisywany w TSS gdy zawieszone jest zdarzenie, i przywracany jest stan z TSS gdy zdarzenie jest ponownie startowane. Oprogramowanie systemowe musi stworzyć przy najmniej jeden TSS odnoszący się przez rejestr zdarzeń TR.
Rys. 1-16 przedstawia deskryptory LDT i TSS - Tryby Dziedziczny / Kompatybilności
1-7.5. Deskryptory bramy
Deskryptory bramy przechowują wskaźniki do segmentów kodu i używane są do sterowania dostępem pomiędzy segmentami kodu w różnymi poziomami uprzywilejowania. Są cztery typy deskryptorów bram:
• Bramy przywołania. Bramy te usytuowane są w GDT lub LDT i używane są do sterowania dostępem pomiędzy segmentami kodu w takim samym zdarzeniu lub w różnych zdarzeniach.
• Bramy przerwań i Bramy Pułapek- Bramy te są umieszczone w IDT i używane są do sterowania dostępem do procedur serwisowania - przerwań.
• Bramy zdarzeń - Bramy te używane są do sterowania dostępem między różnymi zdarzeniami. Używane są również to transferowania sterowania do procedur serwisowania- przerwań, jeżeli te procedury te są same oddzielnymi zdarzeniami.
Rys. 1-17 Tryb Dziedziczny - Deskryptor Przywołania Bramy
1-18 Tryb Dziedziczny - Deskryptory Pułapki Bramy i Bramy Przerwań
Rys 1-19 Tryb Dziedziczny - Deskryptor Bramy- Zdarzenia
Jest kilka różnicy między formatem deskryptora - bramy i formatem deskryptora segmentu - systemu. Różnice te opisane są w następujący sposób, od pozycji bitu najmniej znaczącej do najwięcej znaczącej:
Przesunięcie Celu Segmentu Kodu. 32 bitowe przesunięcie formowane jest przez połączenie bitów 31-16 bajtu +4 z bitami 15-0 bajtu +0. Pole przesunięcia segmentu wyszczególnia punkt wejścia procedury- celu ( przesunięcia) w segmencie. Pole to ładowane jest w rejestr EIP jako rezultat sterowania transferu przy użyciu deskryptora bramy.
Przełącznik Celu Segmentu Kodu. Bity 31-16 bajtu +0. Pole przełącznika segmentu identyfikuje deskryptor segmentu procedurę celu , usytuowanej również w GDT lub LDT. Przełącznik segmentu ładowany jest w rejestr segmentowy CS jako rezultat sterowania transferem przy użyciu deskryptora bramy.
Przełącznik TSS, Bity 31- 16 bajtu +0 (tylko bramy zdarzeń). Pole to identyfikuje deskryptor TSS cel - zdarzenie, umieszczone w każdej z trzech tabel deskryptorów (GDT, LDT, i IDT).
Zliczanie Parametru ( Tylko Bramy Przywołań) Bity 4-0 bajtu +4. Deskryptory Bram - Przywołań w Trybie Dziedzicznym zawierają pole 5 bitowe zliczania - parametru. Pole to wyszczególnia ilość parametrów będących kopiowanych z obecnie wykonywanego stosu programu do sosu programu celu podczas przełączania automatycznego stosu. Automatyczny stos przełączenia są przeprowadzane przez procesor podczas sterowania transferu przez przywołanie bramy do wysokiego poziomu uprzywilejowania. Rozmiar parametru zależy od rozmiaru przywołania bramy wyszczególnionego w typie pola. 32 bitowe bramy przywołania kopiują parametry 4 bajtowe, a 16 bitowe bramy przywołań kopiują 2 bajtowe parametry.
1.8 Tryb długi Deskryptory Segmentów
Interpretacja pól deskryptorów jest zmieniona w trybie długim, i w niektórych przypadkach rozszerzony jest format. Zmiany zależą od trybu operacji. (Tryb kompatybilności lub tryb 64 bitowy) a także od typu deskryptora.
Następujące sekcje opisują zmiany
1.8.1. Deskryptory Segmentu kodu
Segmenty Kodu ciągle istnieją w trybie długim. Segmenty kodu i stowarzyszone z nimi ich deskryptory i przełączniki muszą ustanowić tryb operowania procesora tak samo jak poziom uprzywilejowania.
Atrybut L wyszczególnia czy procesor jest uruchomiony w trybie kompatybilności lub w trybie 64 bitowym.
Rys 1-20 przedstawia format deskryptora segmentu kodu w trybie - długim. W trybie kompatybilności, deskryptor segmentu kodu jest tłumaczony i zachowuje się tak jak to robi w trybie dziedzicznym.
Rys. 1-20, zacieniowane na szaro wskazuje pola deskryptora segmentu kodu, które są ignorowane w trybie 64 bitowym gdy używany jest deskryptor podczas odniesienia do pamięci. Jednakże, pola są ładowane kiedykolwiek ładowany jest rejestr segmentowy w trybie 64 bitowym
Rys 1-20 Tryb Długi - Deskryptor Segmentu Kodu
Ignorowane pola w trybie 64 bitowym. Segmentacja jest uniemożliwiona w trybie 64 bitowym, Cała rozpiętość pamięci wirtualnej segmentów kodu, adresy bazy segmentów kodu są ignorowane. Do celowego przeliczenia wirtualnych adresów, adresy bazy traktowane są jako wartość zero.
Nie jest przeprowadzane sprawdzanie granicy segmentu, i zarówno pole granicy segmentu i bit (G) granulowatowości (ziarnistości) są ignorowane.
Bit atrybut Długi (L). Bit 21 bajtu +4. Tryb długi przedstawia nowe atrybuty, bit długi (L) w deskryptorach segmentu kodu. Bit ten wyszczególnia, że procesor pracuje w trybie 64 bitowym (L=1) lub w trybie kompatybilności (L=0). Gdy procesor pracuje w trybie dziedzicznym, bit ten jest zarezerwowany.
Tryb kompatybilności, utrzymuje binarną kompatybilność z dziedzicznymi aplikacjami 16 bitowymi i 32 bitowymi. Tryb kompatybilności przełączany jest na podstawie segmentu kodu, i pozwala to wcześniejszym aplikacją pracować pod tym samym 64 bitowym oprogramowaniem systemowym. Pracujące oprogramowanie systemowe w trybie długim może wykonywać istniejące 16 bitowe i 32 bitowe aplikacje przez wyczyszczenie bitu L deskryptora segmentu kodu do 0.
Gdy L=0, obserwowane jest wcześniejsze znaczenie bitu D segmentu- kodu i rozmiary adresów i prefiksy , rozmiary operatorów. Segmentacja jest możliwa, gdy L=0. Z punktu widzenia aplikacji, procesor we wcześniejszym środowisku operacji 16 bitowym lub 32 bitowym (zależy do bitu D) nawet jeżeli aktywowany jest tryb długi.
Procesor pracuje w trybie 64 bitowym (L=1), jedyne pasujące ustawienie bitu D jest 0. Ustawienie to tworzy przykładowy rozmiar operatora na 32 bity i przykładowy rozmiar adresów na 64 bity. Kombinacja L=1 i D=1 jest zarezerwowana do przyszłego zastosowania.
"Prefiksy Instrukcji" W wartości 3 opisane są efekty ustawień bitów L i D w segmencie kodu na przykładowych rozmiarach operatorów podczas gdy aktywowany jest tryb długi. Przykładowe rozmiary mogą być unieważnione z rozmiarem operatora, rozmiaru adresów, i prefiksami REX.
1.8.2. Deskryptory segmentu danych.
Segmenty danych ciągle istnieją w trybie długim. Rys 1-21 przedstawia format deskryptora segmentu danych w trybie długim. W trybie kompatybilności, deskryptory segmentu danych są interpretowane i zachowują się jak w trybie dziedzicznym.
N rys. 1-21, zacieniowane na szaro wskazywane są pola które są ignorowane w trybie 64 bitowym gdy deskryptor używany jest podczas odnoszenia się do pamięci. Jednakże, pola są ładowane, kiedykolwiek ładowany jest rejestr segmentowy w trybie 64 bitowym.
Rys. 1-21 Tryb Długi. Deskryptor Segmentu Danych.
Ignorowane pola w trybie 64 bitowym. Segmentacja jest uniemożliwiona w trybie 64 bitowym. Interpretacja adresów bazy segmentu zależy od użytego rejestru segmentowego:
• W deskryptorach segmentu - danych odniesionych przez rejestry segmentowe DS., ES i SS, pole adresów bazy jest ignorowane. W celu przeliczenia adresów wirtualnych, adres bazy traktowany jest jak by miał wartość zero.
• Segmenty danych odniesione przez rejestry segmentowe FS i GS są specjalnie traktowane w trybie 64 bitowym. Dla tych segmentów nie jest ignorowane pole adresów bazy, i nie zerowa wartość może być użyta w obliczeniach adresów wirtualnych. 64 bitowe adresy bazy- segmentu mogą być wyszczególnione przy użyciu specyficznych rejestrów. Spójrz na "Rejestry FS i GS w trybie 64 bitowym.
Nie jest przeprowadzane sprawdzanie granicy segmentu w każdym segmencie w trybie 64 bitowym, i obydwa pole granicy segmentu i bit granulowatowości (ziarnistości) (G) są ignorowane. Bit D/B nie jest używany w trybie 64 bitowym.
Ignorowane są atrybuty typu pół rozszerzeni w dół (E), do zapisu (W), i dostępny (A)
Ignorowane jest pole deskryptora segmentu danych DPL w trybie 64 bitowym, i nie jest przeprowadzane na segmentach danych sprawdzenie przywileju segmentu. Oprogramowanie systemowe może używać mechanizmów ochrony - strony do izolowania i ochrony danych przed nieautoryzowanym dostępem.
1.8.3. Deskryptory Systemu.
W trybie długim, dostępne typy deskryptorów systemu przetworzone przez typ pola są zmieniane. Niektóre typy deskryptorów są modyfikowane, a inne są nielegalne. Zmiany są podsumowane w tabeli 1-6. Próba użycia nielegalnych typów deskryptorów powoduje generalny wyjątek ochrony (#GP).
Wartość Hex |
Typ Pola |
Opis |
|||
|
Bit 11 |
Bit 10 |
Bit 9 |
Bit 8 |
|
0 |
0 |
0 |
0 |
0 |
Zarezerwowane (Nielegalne) |
1 |
0 |
0 |
0 |
1 |
|
2 |
0 |
0 |
1 |
0 |
LDT 64 bitowy |
3 |
0 |
0 |
1 |
1 |
Zarezerwowane (Nielegalne) |
4 |
0 |
1 |
0 |
0 |
|
5 |
0 |
1 |
0 |
1 |
|
6 |
0 |
1 |
1 |
0 |
|
7 |
0 |
1 |
1 |
1 |
|
8 |
1 |
0 |
0 |
0 |
|
9 |
1 |
0 |
0 |
1 |
64 bitowy TSS Dostępne |
A |
1 |
0 |
1 |
0 |
|
B |
1 |
0 |
1 |
1 |
Zajęte 64 bitowy TSS |
C |
1 |
1 |
0 |
0 |
Brama przywołania 64 bitowe |
D |
1 |
1 |
0 |
1 |
Zarezerwowane (Nielegalne) |
E |
1 |
1 |
1 |
0 |
Bram przerwań 64 bitowa |
F |
1 |
1 |
1 |
1 |
Bram pułapka 64 bitowa |
Uwaga: Tylko w trybie 64 bitowym. W trybie kompatybilności, typ wyszczególnia 32 bitowy LDT.
W trybie długim, zmodyfikowane typy deskryptora segmentu systemu.
• 32 bitowy LDT (02h), który jest przedefiniowany jako 64 bitowy LDT.
• Dostępny 32 bitowy TSS (09h), który jest przedefiniowany jako 64 bitowy TSS.
• Zajęty 32 bitowy TSS (0Bh), który jest przedefiniowany jako 64 bitowy TSS.
W trybie 64 bitowym, deskryptory segmentu - systemu LDT i TSS są rozszerzone przez 64 bity, jak to jest przedstawione w rysunku 1-22. N tym rysunku, pola zacieniowane na szaro są ignorowane w trybie 64 bitowym. Rozszerzenia i deskryptory pozwalają im na przechowywanie 64 bitowych adresów bazy, więc ich segmenty mogą być usytuowane gdziekolwiek w przestrzeni adresów wirtualnych. Rozszerzony deskryptor może być ładowany w odpowiedni rejestr tabeli deskryptora (LDTR lub TR) tylko z trybu 64 bitowego. W trybie kompatybilności , wcześniejszy format deskryptora segmentu - systemu, pokazany na rys. 1-16. (Spójrz na instrukcję LLDT i LTR).
Rys 1-22 Tryb 64 bitowy Deskryptor segmentu systemu
64 bitowe adresy bazy segmentu - systemu muszą być w formie kanonicznej. W przeciwnym wypadku generalny wyjątek ochrony zdarzy się z przełącznikiem kodu - błędu, #GP (Przełącznik), gdy ładowany jest segment systemu. Sprawdzane są wartości granicy segmentu systemu przez procesor zarówno w trybie 64 bitowym i trybie kompatybilności, pod kontrolą bitu (G) granulowatowości (ziarnistości).
Rys. 1-22. Przedstawia bity 12-8 bajtu +12 które muszą być wyczyszczone do 0.
Bity te odpowiadają S i typom pól w deskryptorze dziedzicznym. Wyczyszczenie tego bitu do 0 odpowiada do typu nielegalnego w trybie dziedzicznym i powoduje #GP jeżeli próbuje dostać się do górnej połowy trybu 64 bitowego deskryptora segmentu systemu jako deskryptor wcześniejszy.
1.8.4 Deskryptory bramy.
Jak jest przedstawione w tabeli 1-6 , dostępne typy deskryptorów bramy są zmienione w trybie długim. Niektóre typy deskryptorów są modyfikowane i a inne są nielegalne. Zmodyfikowane typy deskryptorów bramy w trybie długim są:
• 32 bitowe przywołanie bramy (0Ch), które jest zmienione na 64 bitowe przywołanie bramy.
• 32 bitowa brama przerwań (0Eh), która przedefiniowana jest jako 64 bitowa brama przerwań
• 32 bitowa brama pułapek (0Fh), która przedefiniowana jest jako 64 bitowa brama pułapek
W trybie długim, kilka typów deskryptorów bram jest nielegalna. Próba użycia tych bram powoduje zdarzenie generalnego wyjątku ochrony (#GP). Nielegalnymi typami bram są:
• 16 bitowa brama przywołania (04h).
• Brama zdarzenia (05h)
• 16 bitowa brama przerwań (06h)
• 16 bitowa brama pułapek (07h).
W trybie długim, deskryptory bram są rozszerzone przez 64 bity, umożliwiając im przechowywanie 64 bitowych przesunięć. 64 bitowy deskryptor bramy przywołania przedstawiony na rysunku 1-23 i 64 bitowa brama przerwań i brama pułapek zawierająca dodatkowe pola IST, która nie jest obecna w bramie przywołań.
Rys. 1-23 Tryb długi - Deskryptor Bramy przywołań
Rys. 1-24 Tryb długi - Deskryptory Bramy pułapek i brama przerwań.
Celem segmentu kodu odniesionego przez deskryptor bramy w trybie długim musi być 64 bitowy segment kodu (CS.L=1, CS.D=0). Jeżeli celem nie jest 64 bitowy segment kodu, zdarzy się generalny wyjątek ochrony #GP. Raportowany błąd kodu zależy od typu bramy:
• Bramy przywołań raportują cel przełącznika segmentu kodu jako kod błędu.
• Bramy pułapek i przerwań raportują numer wektora przerwań jako kod błędu.
Generalny wyjątek ochrony, #GP (0), zdarzy się jeżeli oprogramowanie próbuje odnosić się do deskryptora bramy w trybie długim z przesunięciem segmentu celu, które nie są w formie kanonicznej.
Jest możliwe do oprogramowania przechowywać deskryptory bram w trybie dziedzicznym i długim w tej samej tabeli deskryptorów. Rys. 1-23 przedstawia, iż bity 12-8 bajtu +12 w trybie długim brama przywołań musi być wyczyszczona do 0. Bity te odpowiadają S i typowi pól w wcześniejszej bramie przywołań. Wyczyszczenie tych bitów do 0 odpowiada nielegalnemu typowi w trybie dziedzicznym i zdarzy się #GP jeżeli próbuje dostać się do górnej połowy deskryptora bramy przywołań w trybie 64 bitowym jako wcześniejszy deskryptor bramy przywołań.
Nie jest konieczne wyczyszczenie niektórych bitów w bramie przerwań i w bramie pułapek w trybie długim.
W trybie długim tabela deskryptora przerwań (IDT) musi zawierać 64 bitowe bramy przerwań lub bramy pułapek.. Procesor automatycznie indeksuje IDT przez skalowanie wektora przerwań przez 16. Powoduje to niemożliwy dostęp do górnej połowy bramy przerwań w trybie długim, lub bramy pułapek, jako dziedziczną bramę, gdy procesor pracuje w trybie długim.
Pole IST (Bramy przerwań i pułapek). Bity 2-0 bajtu +4. Deskryptory Bram przerwań i bram pułapek w trybie długim zawierają nowy, 3 bitowe pole tabeli stosu przerwań (IST) nie obecne w wcześniejszych deskryptorach bramy. Pole IST używane jest jako indeks w części IST trybu długiego TSS. Pole IST jest nie 0, indeks odnosi się do wskaźnika IST w TSS, który ładuje procesor w rejestr RSP gdy zdarzy się przerwanie. Jeżeli indeks IST jest 0, procesor używa wcześniejszego mechanizm przełączania - stosu (z niektórymi zmianami) gdy zdarzy się przerwanie. (Spójrz na Tabele Stosu przerwań)
Pole zliczeń (Bramy przywołań). Pole zliczeń znajdujące się w wcześniejszych deskryptorach bramy przywołania nie wspierane w bramach przywoływania w trybie długim. W trybie długim, pole to jest zarezerwowane i powinno być wyczyszczone do zera.
1.8.5. Podsumowanie Deskryptora w trybie długim.
Deskryptory systemu i deskryptory bramy rozszerzone są przez 64 bity do przechowywania adresów bazy 64 bitów w trybie długim lub w trybie 64 bitowym.
Tryb w którym zdarzy się rozszerzenie zależy od celu któremu służy deskryptor, w następujący sposób:
• Tylko rozszerzenie. W trybie 64 bitowym - Deskryptory systemu i pseudo deskryptory które są ładowane w rejestry DGDTR, IDTR, LDTR, i TR są rozszerzone tylko w trybie 64 bitowym. Nie są rozszerzone w trybie kompatybilności.
• Rozszerzenie w trybie długim - Deskryptory bramy (bramy przywołań, bramy przerwań, i bramy pułapek) rozszerzone są w trybie długim (zarówno w trybie 64 bitowym i trybie kompatybilności). Bramy zdarzeń i 16 bitowe deskryptory bramy są nielegalne w trybie długim.
Architektura x86-64 redefiniuje kilka pól wejść deskryptora wspierane w trybie długim. Specyficzna zmiana zależy od tego czy procesor jest w trybie 64 bitowym lub w trybie kompatybilności. Tabela 1-7 podsumowuje zmiany w polu wejścia deskryptora gdy wejście deskryptora ładowane jest w rejestr segmentowy ( w przeciwieństwie do tego gdy rejestr segmentowy później używany jest do dostępu do pamięci).
Tabela Zmian Pól Wejść deskryptora w trybie długim.
Pole deskryptora |
Typ deskryptora |
Tryb długi |
|
|
|
Tryb kompatybilności |
Tryb 64 bitowy |
Granica |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
|
|
Przesunięcie |
Brama |
Rozszerzony do 64 bitów |
Rozszerzony do 64 bitów |
Baza |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
|
|
Przełącznik |
Brama |
Taki sam jak wcześniejszy x86 |
|
IST *1 |
Brama |
Tylko bramy pułapek i przerwań. (Nowy dla typu trybu długiego.) |
|
S i Typ |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
Typy 02h, 09h, i przedefiniowane 0Bh Typu 01h, i 03h są nielegalne |
|
|
|
|
|
|
Brama |
Typy 0Ch, 0Eh i przedefiniowane 0Fh Typy 04h-07h są nielegalne |
|
|
|
|
|
DPL |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
|
|
|
Brama |
|
|
Obecny |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
|
|
|
Brama |
|
|
Przykładowy rozmiar |
Kod |
Taki sam jak wcześniejszy x86 |
D=0 wskazuje adresy 64 bitowe, Dane 32 bitowe D=1 zarezerwowane |
|
Dane |
|
Taki sam jak wcześniejszy x86 |
Długi *1 |
Kod |
Wyszczególnia tryb kompatybilności |
Wyszczególnia tryb 64 bitowy |
Granulowatość (ziarnistość) |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
|
|
Dostępne |
Kod |
Taki sam jak wcześniejszy x86 |
Taki sam jak wcześniejszy x86 |
|
Dane |
|
|
|
System |
|
|
Uwaga: *1 . Nie dostępne (zarezerwowane) w trybie dziedzicznym |
1.9 Przegląd ochrony segmentu
Architektura x86-64 w pełni wspiera wcześniejszy mechanizm ochrony segmentu. Mechanizm ochrony segmentu dostarcza oprogramowaniu systemowemu możliwość zabronienia dostępu programu w inne procedury oprogramowania i danych.
Poziom cząstkowy ochrony segmentu umożliwiony w trybie kompatybilności. Tryb 64 bitowy eliminuje większość sprawdzania typów, i nie jest przeprowadzane sprawdzanie granicy, z wyjątkiem dostępu do tabel deskryptora - systemu.
Preferowana metoda wprowadzania ochrony pamięci systemu operacyjnego w trybie długim jest zależny od mechanizmu ochrony strony jak zostało opisane w "Sprawdzaniu Ochrony Strony". Oprogramowanie systemowe wciąż potrzebuje tworzyć podstawowe struktury danych ochrony segmentu w trybie 64 bitowym. Struktury te są uproszczone, jednakże , przez użycie modelu pamięci płaskiej w trybie 64 bitowym, i ograniczonego sprawdzania segmentacji przeprowadzonego w czasie wykonywania w trybie 64 bitowym.
1.9.1 Koncepcja Poziomu Uprzywilejowania
Ochrona segmentu używana jest do izolacji i programów ochrony i danych ze wszystkich stron. Mechanizm ochrony segmentu wspiera cztery poziomy uprzywilejowania w trybie chronionym. Poziomy uprzywilejowania wyznaczone przez wartość numeryczną od 0 do 3, z 0 będącym najbardziej uprzywilejowanym i 3 będącym najmniej uprzywilejowanym. Oprogramowanie systemowe zwykle przydziela poziomy uprzywilejowania w następujący sposób:
• Poziom uprzywilejowania 0 (najbardziej uprzywilejowany). Poziom ten używany jest przez krytyczne komponenty oprogramowania - systemowego, które wymagają bezpośredniego dostępu do sterowania wszystkimi zasobami procesora i systemu. Może być włącznie z BIOS, z funkcjami zarządzania pamięcią, i uchwytami przerwań.
• Poziom uprzywilejowania 1 i 2 (umiarkowane uprzywilejowanie) - Poziomy te używane są przez mniej krytyczne usługi oprogramowania systemowego, które mogą posiadać dostęp i sterowanie ograniczonego zakresu zasobów procesora i systemu. Oprogramowanie pracuje na tych poziomach uprzywilejowania może zawierać niektóre sterowniki urządzeń i procedury biblioteczne. Te procedury programowe mogą przywoływać bardziej uprzywilejowane usługi oprogramowania systemowego do przeprowadzenia funkcji takich jak przechowywanie śmieci pamięci i alokacje plików.
• Poziom uprzywilejowania 3 (najmniejsze uprzywilejowanie). Poziom ten używany jest przez oprogramowanie aplikacji. Oprogramowanie pracuje na poziomie uprzywilejowanie 3 i normalnie jest wzbraniane przed bezpośrednim dostępem od większości zasobów procesora i systemu. Zamiast tego, dostępy wywołań aplikacji do chronionego procesora i zasobów systemowych przez przywołanie procedur bardziej uprzywilejowanych do przeprowadzenia dostępu.
Rys. 1-25 przedstawia stosunek czterech poziomów uprzywilejowania do każdego z siebie.
1.9.2. Typy poziomów uprzywilejowania.
Poziom uprzywilejowania obecny (CPL) jest poziomem uprzywilejowania przy którym procesor obecnie wykonuje.
CPL zapisany jest w wewnęcznym rejestrze procesora, który jest niewidoczny dla oprogramania. Oprogramowanie zmienia CPL przez przekształcenie sterowania transweru do innego segmentu kodu w nowym poziomem uprzywilejowania.
Deskryptor Poziomu - uprzywilejowania.
Deskryptor poziiomu uprzywilejowania (DPL) jest poziomem uprzywilejowania, który oprogramowanie systemowe przeznacza do indywidualnych segmentów. DPL używane jest do sprawdzenia uprzywilejowania do ustalenia czy oprogramowanie może mieć dostęp do segmentów odniesionych przez deskryptor. W przypadku deskryptorów bramy, DPL ustala czy oprogramowanie może mieć dostęp do odniesienia deskryptora przez bramę. DPL zapisany jest w deskryptorze segmentu (lub bramy).
Wywoływacz Poziomu uprzywilejowania. Wywoływacz Poziomu Uprzywilejowania (RPL) odzwierciedla poziom uprzywilejowania programu, który stworzył przełącznik. RPL może być używany do uwidocznieniu wywoływanemu progrmowi , który zainicjował przywołanie. RPL zapisany jest w przełączniku używanym do odniesienia do deskryptora segmentu (lub bramy).
Następujące sekcje opisują jak CPL, DPL, i RPL używane są przez procesor w przekształceniach sprawdzenia uprzywilejowania na danych
Rys. 1-26 Przykłady sprawdzenia Uprzywilejowania Dostępu Danych
Przykład 1 na rysunku 1-26 przedstawia nie przejście po sprawdzeniu uprzywilejowania dostępu do danych.
Efektywny poziom uprzywilejowania jest 3 ponieważ CPL=3. Wartość ta jest większa niż deskryptora DOP, więc dostęp do segmentu danych jest zabroniony.
Przykład 2 na rysunku 1-26 przedstawia przejście sprawdzenia uprzywilejowania do dostępu do danych. Tu efektywny poziom uprzywilejowania jest 0 ponieważ zarówno CPL i RPL mają wartości 0. Wartość ta jest mniejsza niż deskryptora DOP, więc dostęp do segmentu danych jest umożliwiony, i rejestr segmentu danych jest ładowany.
1.10.2. Udostępnianie Segmentu Stosu.
Przed załadowaniem rejestru segmentu stosu (SS) z przełącznika segmentu, procesor sprawdza poziomy uprzywilejowania w następujący sposób jeżeli dostępy są dozwolone:
Procesor sprawdza czy CPL i przełącznik stosu RPL są równe. Jeżeli nie są równe zdarzy się generalny wyjątek ochrony (#GP) i rejestr SSS nie jest ładowany.
Procesor porównuje CPL z DPL w wejściach tabeli -deskryptora odniesionego przez przełącznik segmentu. Dwie wartości muszą być równe. Jeżeli nie są równe, zdarzy się #GP i rejestr SS nie jest ładowany.
Rys. 1-27. Przedstawia dwa przykłady sprawdzenia uprzywilejowania dostępu - stosu. W przykładzie 1 CPL, przełącznik - stosu RPL, i deskryptor - segmentu stosu DPL są wszystkie równe, więc dostęp do segmentu stosu przy użyciu rejestru SS jest dozwolony. W przykładzie 2, przełącznik- stosu RPL i deskryptor segmentu stosu DPL są obydwa równe. Jednakże , CPL nie jest równy deskryptorowi segmentu - stosu DPL, i dostęp do segmentu stosu przez rejestr SS jest zabroniony.
Rys. 1-27 Przykłady Sprawdzania Uprzywilejowania Dostępu Stosu
1.11 Sprawdzanie Uprzywilejowania Sterowania - Transferem
Sterowanie Transferami między segmentami kodu ( również zwane do sterowania transferami) powoduje że procesor przeprowadza sprawdzenie przywileju by ustalić czy program źródłowy ma możliwość transferu sterowania do programu celowego. Jeżeli przechodzi sprawdzenie przywileju, dostęp do celowego segmentu kodu jest przyznany . Gdy dostęp jest przyznany, celowy przełącznik segmentu kodu ładowany jest w rejestr CS. Rejestr rIP jest aktualizowany z przesunięciem celu CS branego zarówno z operatora dalekiego wskaźnika lub deskryptora bramy. Nie jest przeprowadzane sprawdzenie przywileju podczas bliskiego sterowania transferem, ponieważ takie transfery nie zmieniają segmentów.
Następujące transfery oprogramowania systemowego przy użyciu przywołania systemu i zwracania instrukcji systemowych. SYSCALL i SYSRET są preferowanymi metodami przekształcenia transferów sterowania w trybie długim. SYSENTER i SYSEXIT nie są wspierane w trybie długim.
• Bezpośrednie sterowanie transferami przy użyciu instrukcji CALL i JMP. Omówione to zostało w rozdziale Bezpośrednie sterowanie transferami"
• Brama przywołań steruje transferami przy użyciu instrukcji CALL i JMP.
• Zwracanie sterowania transferami przy użyciu instrukcji RET.
• Przerwania i wyjątki, zawierające instrukcje INT i RET.
• Przełączniki zdarzeń inicjowane przez instrukcje CALL i JMP. Sprzętowe mechanizmy przełączania zdarzenia nie są wspierane w trybie długim.
1.11.1 Bezpośrednie sterowanie transferami.
Bezpośrednie sterowanie transferami zdarza się gdy oprogramowanie wykonuje instrukcje (far-CALL) dalekiego- Przywołania lub (far-JMP) dalekiego-skoku bez użycia bramy przywołania. Poziom przywileju sprawdza typ dostępu umożliwionego jako rezultat bezpośredniego sterowania transferem zależnego czy celowy segment kodu jest dopasowany lub nie jest dopasowany. Deskryptor segmentu kodu dopasowuje bit wskazujący (C ) czy celowy segment kodu jest dopasowany.
Poziomy uprzywilejowania nie są zmienione jako bezpośrednie sterowanie transferem. Stosy programu nie są przełączane automatycznie przez procesor tak jak są przełączane przez bramy przywołań z zmianami uprzywilejowania transferów sterowania.
Nie pasujące segmenty kodu. Oprogramowanie może wykonać bezpośredni transfer sterowania do nie pasującego segmentu kodu tylko jeżeli cel deskryptora segmentu kodu DPL i CPL są równe i RPL jest mniejszy lub równy CPL. Oprogramowanie musi używać bramy przywołania do sterowania transferem bardziej uprzywilejowanego nie pasującego segmentu kodu. W dalekich przywołaniach i skokach, daleki wskaźnik CS:Rip) odnosi się do deskryptora segmentu kodu. Przed załadowaniem rejestru CS z nie dopasowanego przełącznika segmentu kodu. Procesor sprawdza w następujący sposób by sprawdzić czy dozwolony jest dostęp.
Sprawdzenie DPL=CPL Procesor porównuje cel deskryptora segmentu kodu DPL z obecnie wykonywanym programem CPL. Jeżeli są równe, procesor wykonuje następne sprawdzenie. Jeżeli nie są równe, zdarza się generalny wyjątek ochrony. (#GP).
Sprawdzenie RPL<=CPL Procesor porównuje cel deskryptora segmentu kodu RPL z obecnie wykonywanym programem CPL. Jeżeli RPL jest mniejszy lub równy CPL, dostęp jest dozwolony. Jeżeli RPL jest większe niż CPL, zdarza się generalny wyjątek ochrony #GP.
Jeżeli dozwolony jest dostęp, Procesor ładuje rejestry CS i r_IP ich nowymi wartościami zaczyna wykonywanie od usytuowania położenia. CPL jest nie zmieniony. Cel przełącznik CS wartość RPL jest ignorowana, gdy przełącznik ładowany jest w rejestr CS.
Rys. 1-28 pokazuje trzy przykłady sprawdzenia uprzywilejowania wykonywanego jako rezultat dalekiego transferu sterowania do niedopasowanego segmentu kodu. W przykładzie 1, dostęp jest zabroniony ponieważ CPL=DPL i RPL<=CPL. Przykład 2, dostęp jest zabroniony ponieważ CPL różni się od DPL. W przykładzie 3, dostęp jest zabroniony ponieważ RPL>CPL.
Rys 1-28 Niedopasowane przykłady sprawdzenia uprzywilejowania segmentu kodu.
Dopasowane segmenty kodu. W bezpośrednim transferze sterowania do dopasowanego segmentu kodu, cel deskryptor segmentu kodu DPL może być mniejszy niż (przy większym przywileju) niż CPL. Przed załadowaniem rejestru CS z dopasowanym przełącznikiem segmentu kodu, procesor porównuje cel deskryptor segmentu kodu DPL z obecnie wykonywanym programem CPL. Jeżeli DPL jest mniejszy lub równy CPL, dostęp dozwolony. Jeżeli DPL jest większe niż CPL, zdarza się generalny wyjątek ochrony #GP.
W dostępie do dopasowanego segmentu kodu, ignorowane jest RPL i włączone do sprawdzania przywileju.
Gdy dostęp jest dozwolony, procesor ładuje rejestry CS i r_IP nowymi wartościami i zaczyna je wykonywać od położenia celu. CPL jest nie zmieniany . Cel CS wartość deskryptora DPL jest ignorowana dy przełącznik ładowany jest do rejestru CS. Program celowy pracuje na tym samym poziomie uprzywilejowania jak program który przywołał to.
Rys. 1-29 pokazuje dwa przykłady sprawdzania uprzywilejowania wykonanego jako rezultat bezpośredniego sterowanie transferem do dopasowanego segmentu kodu. W przykładzie 1, dostęp jest dozwolony, ponieważ 3ci CPL jest większy niż 0 DPL. Jako cel przełącznika kodu ładowany jest rejestr CS, stara wartość CPL 3 zastępuje wartość RPL przełącznika kodu celu, i program cel wykonuje CPL=3. W przykładzie 2, dostęp jest zabroniony ponieważ CPL<DPL.
Rys 1-29. Przykłady Sprawdzania Pasującego Uprzywilejowania Segmentu Kodu
1.11.2 Transfery sterowania przez Bramy Przywołania.
Transfery przywołania do bardziej uprzywilejowanych segmentów kodu są zrealizowane przez użycie bram przywołania. Bramy przywołania są typami deskryptora który zawiera wskaźniki do deskryptorów segmentu kodu i sterują dostępem do tych deskryptorów. Oprogramowanie systemowe używa bram przywołania do ustanowienia chronionych punktów wejścia w procedurach usług systemowych.
Mechanizm transferu. Operator wskaźnika dalekiego przywołania (far-CALL) lub instrukcji dalekiego skoku (far-JMP) zawierają dwie części przełącznika segmentu kodu (CS) i przesunięcia segmentu kodu (r_IP). W transferze bramy przywołania, przełącznik CS wskazuje deskryptora bramy przywołania częściej niż do deskryptora segmentu kodu, i ignorowany jest r_IP (ale wymagany przez instrukcję).
Rys 1-30 pokazuje transfer sterowania bramy przywołania w trybie dziedzicznym.
Deskryptor bramy przywołania zawiera przełącznik segmentu i pola przesunięcia segmentu. Te dwa pola wykonują tą samą funkcję jako operator wskaźnika w instrukcji bezpośredniego transferu- sterowania. Pole przełącznika segmentu wskazuje do celu deskryptor segmentu kodu. I pole przesunięcia segmentu jest przesunięciem wskaźnika- instrukcji w celowym segmencie kodu. Baza segmentu kodu brana z deskryptora segmentu- kodu dodawana jest do pola przesunięcia w deskryptorze bramy przywołania do stworzenia celowych adresów wirtualnych (adresy liniowe)
Rys 1-30 Mechanizm transferu Bramy przywołania w trybie dziedzicznym
Rys. 1-31 pokazuje transfer sterowania bramy - przywołania w trybie długim. Format deskryptora bramy przywołania w tryb długim jest rozszerzony przez 64 bity do przechowywania pełnego 64 bitowego przesunięcia w przestrzeni adresów wirtualnych. Tylko bramy przywołania mogą być odniesione w trybie długim (64 bitowy tryb i tryb kompatybilności). 32 bitowe typy bram przywołań w trybie dziedzicznym są redefiniowane w trybie długim jako typy 64 bitowe, i 16 bitowe typy bram przywołań są nielegalne.
Rys. 1-31 Mechanizm dostępów Bramy przywołań w trybie długim.
Brama przywołania w trybu długiego muszą odnosić się do 64 bitowego deskryptora segmentu kodu. W trybie 64 bitowym, ignorowane są adresy bazy deskryptora segmentu kodu i pola granicy . Cel Adresy wirtualne w 64 w polu 64bitowym przesunięcia w rozszerzonym deskryptorze bramy przywołania.
Sprawdzenie Uprzywilejowania. Przed załadowaniem rejestru CS z przełącznikiem segmentu kodu usytuowanego w bramie przywołania, procesor wykonuje trzy sprawdzenia uprzywilejowania. Następujące sprawdzenia są wykonane nawet w segmentach kodu dopasowanych i niedopasowanych są odniesione:
Procesor porównuje CPL z bramą przywołań DPL z deskryptorem bramy przywołań (DPL_g) do sprawdzenia przejścia. W innych słowach, następujące wyrażenie musi być prawdziwe CPL<=DPL_g
Procesor porównuje RPL w przełączniku bramy przywołania z DPL_g. RPL musi być numerycznie mniejsze lub równe DPL_g do sprawdzenia tego przejścia. W innych słowach, następujące wyrażenie musi być prawdziwe: RPL<=DPL_g.
Procesor porównuje CPL z celem segmentu kodu DPL od deskryptora segmentu kodu (DPL_s). Typ porównania różni się w zależności od typu transferu sterowania.
Gdy przywołanie lub skok do dopasowanego segmentu kodu - używane jest do sterowania transferu przez bramę przywołania. CPL musi być mumerycznie większe lub równe DPL_s do tego sprawdzenia przejścia. (Sprawdzenie to zapobiega transferami sterowania do mniej uprzywilejowanych programów). Innymi słowy następujące wyrażenie musi być prawdziwe CPL>=DPL_s.
Gdy używane jest instrukcja JMP do sterowania transferem przez bramę przywołania do niedopasowanego segmentu kodu, CPL musi być numerycznie równe DPL do sprawdzenia przejścia. (Instrukcje JMP nie mogą zmienić CPL), Innymi słowy następujące wyrażenie musi być prawdziwe: CPL=DPL_s
Rys. 1-32 pokazuje dwa przykłady sprawdzenia uprzywilejowania bramy przywołania. W przykładzie 1, wszystkie przejścia sprawdzeń przywileju odbywa się w następujący sposób:
• Brama przywołania DPL (DPL_g) jest na najniższym poziomie uprzywilejowania (3), wyszczególnionego przez oprogramowanie (CPL) które pracuje na poziomie uprzywilejowania mogący mieć dostęp do bramy.
• Przełącznik odnosi się do przejścia bramy wywołania, sprawdzenia jej przywileju, ponieważ RPL jest numerycznie mniejsze niż lub równe DPL_g.
• Cel segmentu kodu jest na najwyższym poziomie uprzywilejowania (DPL_s=0. Znaczy to, iż pracujące oprogramowanie może mieć dostęp do celu segmentu kodu na każdym poziomie uprzywilejowania przez bramę przywołań.
(Wstaw rysunek 4-32)
Rys-1-32 Sprawdzenie przywileju. Przykłady dla Bram Przywołań
W przykładzie 2, wszystkie sprawdzenia przywilejów nie przechodzą z następujących powodów:
• Brama przywołań DPL (DPL_g) wyszczególnia że tylko oprogramowanie na poziomie uprzywilejowania 0 może mieć dostęp do bramy. Obecny program nie posiada wystarczającego uprzywilejowania aby mieć dostęp do bramy przywołań, ponieważ CPL jest 2.
• Przełącznik odnosi się do deskryptora bramy przywołań nie ma wystarczającego przywileju do kompletnego odniesienia. RPL jest numerycznie większe niż DPL_g.
• Cel segment kodu jest na niższym przywileju (DPL_s=3 ) niż obecnie pracujące oprogramowanie (CPL=2). Przejścia od bardziej uprzywilejowanego oprogramowania do mniej uprzywilejowanego oprogramowania nie są dozwolone, więc sprawdzenie uprzywilejowania również nie przechodzi.
Chociaż wszystkie trzy sprawdzenia przywileju zawiodły w Przykładzie 2, nie przejście tylko jednego sprawdzenia jest wystarczające do zabronienia dostępu do celu segmentu kodu.
Przełączanie stosu. Procesor wykonuje automatyczne przełączanie stosu, gdy transfer sterowania powoduje zmianę w poziomach przywilejów. Przełączenie stosów izoluje bardziej uprzywilejowane stosy programowe od mniej uprzywilejowanych stosów programowych i dostarcza mechanizm do zachowywania zwracanego wskaźnika do programu, który zainicjował wywołanie.
Gdy przełączanie oprogramowania do bardziej uprzywilejowanego, tak jak to jest zrobione gdy transferowanie sterowania przy użyciu bramy przywołań, Procesor używa odpowiedni wskaźnik stosu (poziom - uprzywilejowania 0, 1, lub 2) przechowywanego w segmencie stosu zdarzenia (TSS). Format wskaźnika stosu zachowanego w TSS zależy od trybu operacyjnego oprogramowania systemowego.
• Oprogramowanie systemowe trybu dziedzicznego przechowuje 32 bitową wartość ESP (przesunięcie stosu) i 16 bitową wartość rejestr przełącznika SS w TSS dla każdego z trzech poziomów uprzywilejowania 0,2, i 2.
•Oprogramowanie systemowe w trybie długim przechowuje 64 bitową wartość RSP w TSS dla poziomów uprzywilejowania 0, 1, 2. Żadna wartość rejestru SS nie jest przechowywana w TSS, ponieważ w trybie długim brama przywołań musi odnosić do 64 bitowego deskryptora segmentu kodu. Tryb 64 bitowy nie używa segmentacji , i wskaźnik stosu zawiera wyłącznie 64 bitowy RSP. Jakakolwiek wartość ładowana do rejestru SS jest ignorowana.
Spójrz na "Zarządzanie zasobami" dla znalezienia informacji o trybie dziedzicznym i formatach TSS w trybie długim.
Rys 1-33 pokazuje 32 bitowy stos w trybie dziedzicznym przed i po automatycznym przełączeniu stosu. Ten szczególny przykład zakłada że parametry przeszły od obecnego programu do programu celowego. Po procesie następuje tryb dziedziczny w przełączaniu stosów i kopiowaniu parametrów jest:
Celowy segment kodu DPL jest czytany przez procesor i używany jako indeks TSS do wybrania nowego wskaźnika stosu (SS:ESP). Na przykład, jeżeli DPL=1, procesor wybiera SS:ESP dla poziomu uprzywilejowania 1 z TSS.
Rejestry SS i ESP ładowane są z nowymi wartościami SS:ESP czytanymi z TSS.
Stare wartości rejestrów SS i ESP nakładane są na stos wskazywany przez nowy SS:ESP.
Pole zliczania 5 bit czytane jest z deskryptora przywołania bramy
Ilość parametrów wyszczególnionych w polu zliczania (do 31) kopiowane są z starych do nowych stosów. Rozmiar parametrów kopiowanych przez procesor zależy od rozmiaru bramy przywołania: 32 bitowe bramy przywołania kopiują 4 bajtowe parametry i 16 bitowe bramy przywołania kopiują 2 bajtowe parametry.
Zwracany wskaźnik nakładany jest na stos. Zwracany wskaźnik zawiera obecną wartość rejestru CS i EIP instrukcji następuje po instrukcji przywołania.
Rejestr CS ładowany jest z pola przełącznika segmentu w deskryptorze bramy przywołania, i EIP ładowany jest z pola przesunięcia w deskryptorze bramy przywołania.
Program celowy zaczyna wykonywać się z instrukcjami odniesionymi przez nowe CS:EIP.
Rys. 1-33 32 bitowy przełącznik stosu w trybie dziedzicznym, z parametrami.
Rys 1-34 przedstawia 32 bitowy stos w trybie dziedzicznym przed i po automatycznym przełączaniu stosu gdy żadne parametry nie przeszły (licznik=0). Większość oprogramowania nie używa pola licznika deskryptora przywołania bramy do parametrów przejściowych. Oprogramowanie systemowe zwykle definiuje mechanizmy łączenia które nie zależą od automatycznego kopiowania parametrów.
Rys 1-32 32 bitowy przełącznik Stosu, Tryb dziedziczny baz parametrów
Rys. 1-35 przedstawia przełącznik stosu w trybie długim. W trybie długim, wszystkie bramy przywołania muszą odnosić się do deskryptorów segmentu kodu, więc przełącznik stosu w trybie długim używa 64 bitowego stosu. Procesy przełączania stosów w trybie długim są podobne do przełączania w trybie dziedzicznym gdy nie przechodzi żaden parametr. Odbywa się to w następujący sposób:
Cel segment kodu DPL czytany jest przez procesor i używany jako indeks w 64 bitowym TSS do wybierania nowego wskaźnika stosu (RSP).
Rejestr RSP ładowany jest z nową wartością RSP czytaną z TSS. Rejestr SS ładowany jest z pustym przełącznikiem (SS=0). Ustawienie przełącznika SS na pusty pozwala odpowiedniemu przejęciu zagnieżdżonych transferów sterowania w trybie 64 bitowym. Zobacz dla dodatkowych informacji "Zagnieżdżone zwroty do procedur w trybie 64 bitowym"
Jako w trybie dziedzicznym, jest to wskazane utrzymać poziom uprzywilejowania wywoływacza segmentu stosu (SS.RPL) równego obecnemu poziomowi uprzywilejowania (CPL). Podczas użycia bramy przywołania do zmiany poziomów uprzywilejowania. SS.RPL jest uaktualniany do odbicia nowego CPL. SS.RPL jest przywracany z powrotu celu CS.RPL na późniejszym dalekim powrocie zmiany poziomu przywileju.
Stara wartości rejestrów SS i RSP są nakładane na wskazany stos przez nowy RSP. Stara wartość SS i zdejmowana późniejszy daleki powrót. Pozwala to oprogramowaniu systemowemu ustawić przełącznik SS do procesów w trybie kompatybilności przez wykonanie RET (lub IRET) które zmienia poziom uprzywilejowania.
Wskaźnik powrotu jest nakładany na stos. Wskaźnik powrotu zawiera wartość obecnego rejestru CS i instrukcji RIP następujące instrukcje przywołania.
Rejestr CS ładowany jest z pola przełącznika segmentu w deskryptorze bramy przywołania w trybie długim i ładowany jest RIP z pola przesunięcia w deskryptorze bramy przywołania w trybie długim.
Program celowy zaczyna wykonanie z odniesioną instrukcją przez nowe RIP.
Rys. 1-35 Przełącznik stosu w trybie długim
Wszystkie nakładania stosu wynikające ze zmiany poziomu uprzywilejowania do dalekich przywołań są osiem bajtów szerokie i powiększają RSP przez osiem. Tryb długi ignoruje pole licznika bramy przywołania i nie wspiera automatycznego wyposażenia kopiowanego parametru znajdującego się w trybie dziedzicznym. Oprogramowania może mieć dostęp do parametrów na starym stosie, jeżeli jest to konieczne, przez odniesienie do starego przełącznika stosu i wskaźnika stosu zachowanego na nowym stosie procesów.
1.11.3 Transfery sterowania powrotu.
Powroty do wywołania programów mogą być wykonywane przez użycie instrukcji RET.
Są następujące typy powrotów:
• Powrót bliski - Powrót bliski wykonuje transfery sterowania w czasie tego samego segmentu kodu, więc rejestr CS pozostaje niezmieniony. Nowe przesunięcie jest zdejmowane ze stosu i w rejestrze r_IP.
Nie wykonywane są sprawdzania przywilejów.
• Powrót daleki, Taki sam przywilej - Powrót daleki transferuje sterowanie od jednego segmentu kodu do drugiego. W czasie gdy segment kodu jest pierwotnie nienaruszony, wskaźnik daleki (CS:r_IP) zdejmuje stos i jest sprawdzany RPL nowego segmentu kodu (CS). Jeżeli wywołane poziomy przywileju (RPL) dobiera obecny poziom przywileju (CPL), wtedy zrobiony jest powrót do tego samego poziomu przywileju. Zapobiega to oprogramowaniu od zmieniania wartości CS na stosie w próbie powrotu do wyżej uprzywilejowanego oprogramowania.
• Powrót daleki, Mniejszy przywilej - Powrót daleki może zmienić poziom przywileju, ale tylko do mniejszego poziomu uprzywilejowania. W tym przypadku przełącznik stosu wykonywany jest między obecnym programem, o wyższym przywileju i programem powrotu mniejszego przywileju. Wartości rejestru CS i r_IP są zdejmowane ze stosu. Wskaźnik stosu o mniejszym przywileju jest również zdejmowany ze stosu i w rejestrach SS i r_sp. Procesor sprawdza obydwa poziomu przywilejów rejestrów CS i SS by upewnić się że są równe i są na mniejszym poziomie uprzywilejowania niż obecny CS.
W przypadku zagnieżdżonych powrotów w trybie 64 bitowym, pusty przełącznik może być zdjęty w rejestrze SS.
Powroty dalekie również sprawdzają poziomy uprzywilejowania rejestrów DS., ES, FS i przełącznika GS. Jeżeli jakiś z tych rejestrów segmentowych ma przełącznik na wyższym przywileju niż powrót programu. Rejestr segmentowy ładowany jest pustym przełącznikiem.
Przełączanie stosu. Przełączenie stosu wykonane przez powrót daleki do mniejszego poziomu uprzywilejowania, z wyjątkiem tych parametrów nie są automatycznie kopiowane jako część powrotu. Procesy następujące przez przełączenie stosu dalekiego wywołania w trybie długim i w trybie dziedzicznym jest:
Powrót segmentu kodu RPL czytany jest przez procesor od wartości CS zapisanej na stosie ustanawiając że zdarza się transfer sterowania w mniejszym przywileju.
Wskaźnik instrukcji programu powrotu zdejmowany jest z obecnego stosu programu (wyższy przywilej) i ładowany jest w rejestry CS i r_IP.
Instrukcja powrotu może zawierać operator natychmiastowy, który wyszczególnia ilość dodatkowych bajtów będących zdjętych ze stosu. Bajty te mogą odpowiadać paramatrom nakładanych na stos obecnie przez przywołanie przez bramę przywołania zawierającą nie zerowe pole licznika parametru. Jeżeli powrót zawiera operator natychmiastowy, wtedy wskaźnik stosu ustawiany jest w górę przez dodanie wyszególnionej ilości bajtów do r_SP.
Wskaźnik stosu powrotu programu zdejmowany jest ze stosu obecnego programu (wyższy przywilej) i ładowany jest w rejestry SS i r_SP. W przypadku zagnieżdżonych powrotów do trybu 64 bitowego, pusty przełącznik może być nałożony w rejestr SS.
Rozmiar operatora dalekiego powrotu ustanawia rozmiar nałożeń stosu w czasie przełączania stosów. Jeżeli używany jest daleki powrót w trybie 64 bitowym powrót z ważniejszego przywołania przez bramę przywołania w trybie długim, dalekie wywołanie musi używać 64 bitowego rozmiaru operatora. 64 bitowy rozmiar operatora pozwala dalekiemu powrotowi odpowiednio czytać stos ustanowiony obecnie przez dalekie przywołanie.
Zagnieżdżone powroty do procedur w trybie 64 bitowym. W trybie długim, dalekie wywołanie, które zmienia poziomy uprzywilejowania powoduje ładowanie rejestru SS pustym przełącznikiem (Jest to ta sama akcja podjęta prze przerwanie w trybie długim). Jeżeli wywołana procedura wykonuje inne dalekie wywołanie do procedury o wyższym przywileju, lub jest przerwana, pusty przełącznik SS nakładany jest na ramkę stosu, i inny przełącznik pusty ładowany jest w rejestr SS. Użycie pustego przełącznika w ten sposób pozwala procesorowi odpowiednio przechwycić zagnieżdżone wywołania podczas trybu 64 bitowego wykonywania procedur i uchwytów przerwań.
Normalnie, RET które zdejmuje pusty przełącznik w rejestrze SS powoduje zdarzenie generalnego wyjątku ochrony #GP. Jednakże, w trybie długim, pusty przełącznik zachowuje się jak wskazująca flaga istnienia zagnieżdżonych uchwytów przerwań lub innego uprzywilejowanego oprogramowania w trybie 64 bitowym. Tryb długi pozwala instrukcji RET zdjąć pusty przełącznik w rejestrze SS ze stosu pod następującymi warunkami:
• Celowy tryb jest trybem 64 bitowym.
• Celowe CPL jest mniejsze niż 3.
W tym przypadku procesor nie ładuje deskryptora SS, i pusty przełącznik ładowany jest w SS bez spowodowania wyjątku #GP.
1.12. Sprawdzenie granicy.
Z wyjątkiem trybu 64 bitowego, sprawdzanie granicy wykonywane jest przez wszystkie instrukcję które odnoszą się do pamięci. Sprawdzenie pamięci odkrywa próby dostępu do pamięci na zewnątrz obecnego ograniczenia segmentu, próby wykonywania instrukcji na zewnątrz obecnego segmentu kodu, indeksowanie na zewnątrz obecnego deskryptora tabeli. Jeżeli nie przechodzi instrukcja sprawdzenia granicy, zarówno (1) zdarza się generalny wyjątek ochrony dla wszystkich innych naruszeń granicy segmentu lub (2) zdarza się wyjątek uszkodzenia stosu dla naruszeń granicy segmentu stosu.
W trybie 64 bitowym, granice segmentu nie są sprawdzane podczas dostępów do jakiegokolwiek segmentu odniesionego przez rejestry CS, DS., ES, FS, GS, i przełącznik rejestrów SS. Zamiast tego procesor sprawdza czy adresy wirtualne używane do odnoszenia się do pamięci są w formie adresów kanonicznych
W trybie 64 bitowym, jako tryb dziedziczny i kompatybilny, sprawdzane są granice tabeli deskryptora.
1.12.1 Ustalenie Naruszenia granicy
Aby ustalić naruszenie granicy segmentu, procesor sprawdza adresy wirtualne (liniowe), by ustalić jeżeli zawiedzie na zewnątrz pasującego zakresu przesunięcia segmentu ustalonego przez pole granicy segmentu w deskryptorze. Jeżeli jakaś część operatora lub instrukcji wypadnie na zewnątrz r zakresu przesunięcia segmentu, zdarzy się naruszenie granicy. Na przykład, dostęp podwójnego słowa, dwa bajty z górnego ograniczenia segmentu, powoduje naruszenie segmentu ponieważ połowa podwójnego słowa jest na zewnątrz segmentu.
Trzy bity z wejścia deskryptora używane są do sterowania jak pole granicy segmentu jest interpretowane: bit granulowatości (ziarnistości) (G), bit rozmiaru przykładowego operatora (D), bit rozszerzenia w dół segmentu danych (E).
Dla wszystkich segmentów innych niż segmenty rozszerzone w dół, minimum przesunięcia segmentu jest 0. Maksimum przesunięcia segmentu zależy od wartości bitu G:
• Jeżeli G=0 (bajt granulowatowości ) (ziarnistości), maksimum dozwolone przesunięcie segmentu równe jest wartości pola granicy segmentu.
• Jeżeli G=1 (4096 bajtów granulowatowości) (ziarnistości), pole granicy segmentu jest skalowane pierwsze przez 4096 (1000h). Wtedy 4096 (0FFFh) dodane jest do wartości skalowanej do dojechania do maksimum dozwolonego przesunięcia segmentu, jak pokazano w następującym równaniu:
minimalne przesunięcie segmentu = (granica x 1000h) + 0FFFh +1
Na przykład, jeżeli pole granicy segmentu jest 0100h, wtedy minimalne dostępne przesunięcie segmentu jest:
(0100h x1000h)+0FFFh + 1=10_1000h.
Dla segmentów rozszerzonych w dół, maksymalny rozmiar segmentu jest wyszczególniony gdy wartość granicy segmentu jest 0.
1-13 Sprawdzanie typu
Sprawdzanie typu zapobiega oprogramowaniu od użycia deskryptorów w pasujące sposoby. Nie przechodzące rezultaty sprawdzenia typu w wyjątku. Sprawdzenie typu wykonane jest przy użyciu pięciu bitów od wejścia deskryptora: bit S i 4 bitowe pole typu . Razem, te pięć bitów używane są do wyszczególnienia typu deskryptora (kodu, danych, segment lub brama) i ich charakterystyka dostępu. Sprawdzenie typu wykonywane jest przez procesor w trybie kompatybilności tak jak w trybie dziedzicznym. Ograniczone sprawdzanie typu wykonywane jest w trybie 64 bitowym.
1.13.1 Sprawdzanie typu w trybie dziedzicznym i w trybie kompatybilności.
Sprawdzanie typu wykonane jest w trybie dziedzicznym i w trybie kompatybilności wyszczególnione w następujących sekcjach.
Tabela deskryptora ładuje rejestr. Ładuje w rejestry tabel deskryptory LDTR i TR i sprawdzane do odpowiedniego typu segmentu systemu. LDTR może być tylko ładowane z deskryptorem LDT, i TR tylko z deskryptorem TSS. Sprawdzenie wykonywane jest podczas jakiejś akcji która powoduje, że te rejestry są ładowane . Zawiera to wykonanie instrukcji LLDT i LTR i podczas przełączeń zdarzeń.
Ładowanie rejestru segmentowego. Następujące ograniczenia usytuowane są na typach deskryptorów segmentu, które mogą być ładowane w sześć rejestrów segmentowych użytkownika:
• Tylko segmenty kodu mogą być ładowane w rejestr CS.
• Tylko segmenty danych do zapisu mogą być ładowane w rejestr SS.
• Tylko następujące typy segmentów mogą być ładowane w rejestry DS., ES, FS lub GS.
Segmenty danych - tylko do odczytu lub odczyt zapis,
Segmenty kodu - do odczytu.
Sprowadzenia te wykonywane są podczas jakiejś akcji, która spowoduje, że rejestry segmentowe będą ładowane.
Zawiera to wykonanie instrukcji rejestru segmentu MOV, transferów sterowania, i przełączników zdarzeń.
Transfery sterowania. Transfery sterowania (rozgałęzienia i przerwania) zawierają dodatkowe ograniczenia na typach segmentów, które mogą być odniesione podczas transferu:
• Typ deskryptora segmentu odniesionego przez dalekie przywołania (far CALLs) i daleki skoki (far JMPs) które muszą być jednym z następujących rzeczy:
Segment kodu,
Bramą zdarzeń lub bramą przywołań,
Dostępną TSS (dostępną tylko w trybie dziedzicznym),
Bramą zdarzeń (dostępną tylko w trybie dziedzicznym),
• Tylko deskryptorami segmentu kodu mogącymi być odniesionymi przez bramę przywołań, bramę przerwań, i deskryptory bramy pułapek,
• Tylko deskryptory TSS mogą być odniesione przez deskryptory bramy przywołań.
• Pole połączenia linku (przełącznika) w TSS mogą tylko wskazywać do deskryptora TSS. To sprawdzone w czasie transferu sterowania IRET do zdarzenia.
• Instrukcje daleki RET i dalekie IRET mogą tylko odnosić się do deskryptorów segmentu kodu.
• Tabela deskryptora przerwań (IDT), która odniesiona jest podczas transferów sterowania przerwaniami, mogą tylko zawierać bramy przerwań, bramy pułapek, i bramy zdarzeń.
Dostępy segmentów. Po tym jak deskryptor segmentu jest z sukcesem załadowany w jeden z rejestrów segmentowych, czytanie i zapisywanie w segmentach jest zabronione w następujący sposób:
• Zapisy nie są dozwolone w typach segmentów danych tylko do odczytu.
• Zapisy nie są dozwolone w typach segmentów kodu (segmentów wykonywalnych).
• Odczyty z typów segmentów kodu nie są dozwolone, jeżeli bit do odczytu (R ) jest wyczyszczony do 0.
Sprawdzenia te, są generalnie wykonywane podczas wykonywania instrukcji, które mają dostęp do pamięci.
1-13.2 Różnice w sprawdzeniu typu w trybie długim.
Tryb kompatybilności i w trybie 64 bitowym. Następujące sprawdzenia typów różnią się w trybie długim (tryb 64 bitowy i tryb kompatybilności) w porównaniu do trybu dziedzicznego:
• Segmenty systemu - Typy segmentu systemu sprawdzane są, ale następujące typy które pasują w trybie dziedzicznym są nielegalne w trybie długim:
Dostępne 16 bitowe TSS.
Zajęte 16 bitowe TSS.
Przetworzenie pola typu 00h w górnej połowie deskryptora segmentu systemu do wskazania typu nielegalnego i zapobiegnięciu dostępom do jako deskryptorowi dziedzicznemu.
• Bramy - Typy deskryptora bramy sprawdzane są, ale następujące typy które są pasujące w trybie dziedzicznym są nielegalne w trybie długim:
16 bitowa brama przywołania.
16 bitowa brama przerwań.
16 bitowa brama pułapek
Brama zdarzeń.
Tryb 64 bitowy. Tryb 64 bitowy uniemożliwia segmentację, i większość pól deskryptorów segmentów jest ignorowana.
Następująca lista identyfikuje sytuację, gdzie sprawdzenia typu w trybie 64 bitowym różnią się od tych w trybie kompatybilności i w trybie dziedzicznym.
• Segmenty kodu - Bit typu do odczytu (R ) w trybie 64 bitowym jest ignorowany. Żadne ze sprawdzeń typu dziedzicznego, które zapobiega czytaniu z i zapisu w segmenty kodu nie są wykonywane w trybie 64 bitowym.
• Segmenty danych - Atrybuty segmentów danych są ignorowane w trybie 64 bitowym. Bity typu do zapisu (W), i rozszerzenia w dół (E) są ignorowane. Wszystkie segmenty danych traktowane są do zapisu.
35
1
35
KOD
STOS
DANE
BRAMA
SEGMENT STANU-ZDARZENAI
TABELA DESKRYPTORA LOKALNEGO
DESKRYPTOR
DESKRYPTOR
DESKRYPTOR
DESKRYPTOR
DESKRYPTOR
DESKRYPTOR
DESKRYPTOR BRAMY
DESKRYPTOR BRAMY
DESKRYPTOR BRAMY
....
....
....
....
PRZEŁĄCNIK 1
PRZEŁĄCNIK 2
PRZEŁĄCNIK n
TABELA DESKRTYPOR-PRZERWAN (IDT)
TABELA DESKRYPTORAA LOKALNEGO
TABELA DESKKRYPTORA GLOBALNEGO (GDT)
PRZEŁĄCZNIKI SEGMENTU
REJESTR TABELI DESKRYPTORA GLOBALNEGO
REJESTR TABELI DESKRYPTORA PRZERWAŃ
REJEST TABELI DESKRYPTORRA LOKALNEGO
REJESTR ZDARZEŃ
REJESTR SEGMENTU STOSU
REJESTRY SEGMENTU DANYCH
REJESTR SEGMENTU KODU
TR
LDTR
IDTR
GDTR
ES
DS
FS
GS
SS
CS
RPL
T
I
SI
15
3 2 1 0
PRZEŁĄCZNIK
ATRYBUTY SEGMENTU
32 bitowa granica segmentu
32 bitowa podstawa adresów segmentowych
Ukryte przed oprogramowaniem
*
+
+
Tabela deskryptora
przerwań
Wektor przerwań
Rozmiar wejścia deskryptora
Adresy bazowe IDT Granica IDT
Rejestr tabeli deskryptora przerwań
+4
+0
31 24 23 22 21 19 16 15 14 13 12 11 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Adresy bazowe 23-16
Typ
S
DPL
P
Granica
Segmentów 19-16
A
V
L
D
/
B
G
Adresy bazowe 31-24
A
R
C
+4
+0
31 24 23 22 21 19 16 15 14 13 12 11 10 9 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Adresy bazowe 23-16
1
1
DPL
P
Granica
Segmentów 19-16
A
V
L
D
/
B
G
Adresy bazowe 31-24
32 bitowa granica segmentu
64 bitowe adresy bazy segmentu
Atrybuty segmentu
Przełącznik
Ukryte przed oprogramowaniem
A
W
E
+4
+0
31 24 23 22 21 19 16 15 14 13 12 11 10 9 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Adresy bazowe 23-16
0
1
DPL
P
Granica
Segmentów 19-16
A
V
L
D
/
B
G
Adresy bazowe 31-24
+4
+0
Zarezerwowane
IGN
Typ
31 24 23 22 21 19 16 15 14 13 12 11 10 9 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Adresy bazowe 23-16
Typ
0
DPL
P
Granica
Segmentów 19-16
A
V
L
I
G
N
G
Adresy bazowe 31-24
Przesunięcie Celu Segmentu Kodu 15-0
Zliczanie
parametru
0
DPL
P
+4
+0
+4
+0
+4
+0
Przełącznik Celu Segmentu Kodu 15-0
Przesunięcie Celu Segmentu Kodu
31 24 23 22 21 19 16 15 14 13 12 11 10 9 8 7 0
Typ
Przesunięcie Celu Segmentu Kodu 15-0
Zarezerwowane IGN
0
DPL
P
Przełącznik Celu Segmentu Kodu 15-0
Przesunięcie Celu Segmentu Kodu
31 24 23 22 21 19 16 15 14 13 12 11 10 9 8 7 0
Typ
Zarezerwowane IGN
Zarezerwowane IGN
S
DPL
P
Przełącznik TSS
Zarezerwowane IGN
31 24 23 22 21 19 16 15 14 13 12 11 10 9 8 7 0
Granica
Segmentów 19-16
+4
+0
S
DPL
31 24 23 22 21 19 16 15 14 13 12 11 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Adresy bazowe 23-16
1
P
A
V
L
D
G
Adresy bazowe 31-24
L
1
C
R
A
A
W
E
0
+4
+0
31 24 23 22 21 19 16 15 14 13 12 11 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Adresy bazowe 23-16
1
S
DPL
P
Granica
Segmentów 19-16
A
V
L
L
D
G
Adresy bazowe 31-24
Typ
0
Adresy bazowe 63-32
0
0
0
0
31 24 23 22 21 19 16 15 14 13 12 11 8 7 0
Granica segmentu 15-0
Adresy bazowe 15-0
Zarezerwowane, IGN
0
DPL
P
Granica
Segmentów 19-16
A
V
L
Adresy Bazy 23 -16
G
Adresy bazowe 31-24
Zarezerwowane, IGN
+12
+8
+4
+0
Typ
S
Przesunięcie celu 63-32
0
0
0
0
31 24 23 22 21 19 16 15 14 13 12 11 8 7 0
Granica segmentu 15-0
Przełącznik celu
Zarezerwowane, IGN
0
DPL
P
S
Przesunięcie celu 63-32
Zarezerwowane, IGN
Typ
Przesunięcie celu 31-16
Zarezerwowane, IGN
+12
+8
+4
+0
Przywilej Ewektywny
E
Max
Programy aplikacji
Zarządzanie pamięcią, Alokacja plików, Przechwytywanie przerwań
31 24 23 22 21 19 16 15 14 13 12 11 8 7 0
Granica segmentu 15-0
Przełącznik celu
Sterowniki urządzeń
Procedury biblioteczne
Uprzywilejowanie 0
DPL
P
Zarezerwowane, IGN
Przesunięcie celu 31-16
Zarezerwowane, IGN
+12
+8
+4
+0
<=
DPL=2
RPL=0
CPL=3
CS
Przełącznik danych
Deskryptor
Segment
Danych
Przykład 1: Sprawdzenie uprzywilejowania zabrania
Dostęp zabroniony
Dostęp umożliwiony
Przykład 2: Sprawdzenie uprzywilejowania przechodzi
Deskryptor
Przełącznik danych
DPL=2
<=
Segment
Danych
Przywilej Ewektywny
E
Max
RPL=0
CPL=0
CS
Dostęp umożliwiony
Przykład 1: Sprawdzenie uprzywilejowania przechodzi
Deskryptor
Przełącznik danych
DPL=3
Dostęp uniemożliwiony
Segment
Danych
Przykład 2: Sprawdzenie uprzywilejowania nie przechodzi
=
RPL=3
CPL=3
CS
Deskryptor
Przełącznik danych
DPL=3
Segment
Danych
=
RPL=3
CPL=2
CS
Dostęp umożliwiony
Przykład 1: Sprawdzenie uprzywilejowania przechodzi
Deskryptor
=
DPL=2
Segment
Danych
<=
CPL=2
CPL=0
CS
?
Przełącznik segmentu
Instrukcja Przesunięcia
Daleki wskaźnik
Przesunięcie Segmentu Kodu
DPL
Przełącznik Segmentu Kodu
Granica segmentu kodu
DPL
Baza Segmentu Kodu
+
Deskryptor segmentu kodu
Deskryptor Bramy Przywołania
Adresy wirtualne
Segment Kodu
Tabela deskryptora
Tabela deskryptora
Nie używane
Adresy wirtualne
Deskryptor Bramy Przywołania
Deskryptor segmentu kodu
Przesunięcie Segmentu Kodu (63:32)
Granica segmentu kodu
Baza Segmentu Kodu
DPL
DPL
Przełącznik Segmentu Kodu
Przesunięcie Segmentu Kodu (31:0)
Daleki wskaźnik
Instrukcja Przesunięcia
Przełącznik segmentu
Przestrzeń Adresów Wirtualnych
+(n-1)*4
+(n-2)*4
Stare SS:ESP
+(n*4)+12
+(n*4)+8
+(n*4)
+(n*4)+4
+8
+4
Przełącznik stosu
Stare EIP
Nowe SS:ESP
Stare CS
Parametr n
Parametr 2
Parametr 1
Stare ESP
Stare SS
Nowy 32 bitowy stos po przywołaniu
Stary 32 bitowy stos przed przywołaniem
Parametr 2
Parametr 1
Parametr n
+12
Przełącznik stosu
Nowe SS:ESP
Nowy 32 bitowy stos po wywołaniu CALL
+8
+8
+16
+24
Przełącznik stosu
Nowe RSP
(SS=0 + nowy_CPL
Stary 64 bitowy stos przed wywołaniem CALL
Stare SS:RSP
+4
Stare RIP
Stare CS
Stare RSP
Stare SS
Nowy 64 bitowy stos po wywołaniu CALL
Stary 32 bitowy stos przed wywołaniem CALL
Stare SS:ESP
Stare EIP
Stare CS
Stare ESP
Stare SS
Dostęp zabroniony
Przykład 2: Sprawdzenie uprzywilejowania nie przechodzi
Deskryptor Bramy przywo.lań
Przełącznik bramy przywołań
DPLg=0
Segment
Danych
DPLs=3
RPL=3
CPL=2
CS
Deskryptor segmentu kodu