Asembler x86/Zaawansowana architektura: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
błąd językowy
literówki
Linia 17:
*<font color ="green">TI</font> - (ang. Table Indicator) oznacza, czy dany deskryptor segmentu znajduje się w GTK (gdy TI = 0) lub w LDT (gdy TI = 1). Pole to zajmuje bit nr 2.
 
Selektor segmentu zapisywany jest w rejestrze segmentowym jak CS, DS, SS, ES,FS, GS. Gdy posiadamy pewny '''adres logiczny''' np. 0xc00d:1001 wówczas wartość 0xC00D będzie właśnie w pewnym rejestrze segmentownymsegmentowym i bedziebędzie stanowić selektor segmentu, nie zaś jego adres (de facto takowy segment w rzeczywistości nie istnieje - patrz "Płaski model pamięci").
 
 
Każdy nasz "logiczny segment" jest reprezentowany przez tzw '''deskryptor segmentu''', o długości 8 bajtów (64 bity). Deskryptor ten zaś jak sama nazwa wskazuje opisuje nasz segment. WspomianyWspomniany deskryptor znajduje się w tablicy deskryptorów. Mogłeś sobie postawić pytanie: "W której ? Przecież są dwie tablice: GDT i LDT" Odpowiedź: "To zależy od pola TI w selektorze segmentu". Poniżej znajduje się obrazek prezentujący jak wygląda deskryptor segmentu wraz z wytłumaczeniem danych pól.
 
[[Grafika:Deskryptory.PNG|640px]]
 
*<font color ="green">Base</font> - tutaj znajduje się adres liniowy pierwszego bajtu danego segmentu.
*<font color ="green">G </font>- (ang. Granularity flag) jeśli ta flaga jest ustawiona na 0 (wyczyszczona), wówczas wielkość semgnetusegmentu jest podawana w pojedyńczychpojedynczych bajtach, np 78 B albo 256 B. W przeciwnym wypadku rozmiar wyraża się w wielokrotności 4096 bajtów (4 KB).
*<font color ="green">Limit</font> - Przetrzymuje offset (przesunięcie) ostatniej komórki pamięci danego segmentu. Ta flaga ma związek z flagą G. Gdy G = 0 wówczas wielkość segmentu może wynosić od 1 bajta do 1 MB (czyli maksimum pamięci jaki mógł mieć procesor w trybie rzeczywistym) gdy G = 1 wówczas segment może mieć wielkość od 4 KB (rozmiar strony - o tym nieco później) aż do 4 GB.
*<font color ="green">S</font> - (ang. system flag) jeśli ta flaga jest wyzerowana dany segment jest tzw '''segmentem systemowym''', który przechowuje bardzo ważne struktury danych systemowych jak np położenie LDT. Jeśli S = 1 wówczas dany segment jest zwykłym segmentem kodu albo danych. Zwróc uwagę na nieco nietypowe ustawienie flag. Do tej pory jeśli dana flaga jest ustawiona na 1 wówczas spełnia swoją funkcję. W fladze S jest odwrotnie, tylko jeśli jest wyczyszczona zaczyna spełniać swoją rolę.
*<font color ="green">Type</font> - ta flaga determinuje typ segmentu. Może oznaczać, że dany segment (również deskryptor segmentu) jest albo DeskrytporemDeskryptorem Segmentu Kodu (ang. Code Segment Descriptor - CSD) albo DeskrytporemDeskryptorem Segmentu Danych (ang. Data Segment Descriptor - DSD) albo DeskrytporemDeskryptorem Segmentu Stanu Zadania (ang. Task State Segment Descriptor - TSSD).
*<font color ="green">DPL</font> - (ang. Descriptor Privilege Level) służy do ograniczenia dostępu do danego segmentu. DPL reprezentuje '''minimalny''' stan uprzywilejowania CPU wymagany do użycia tego segmentu. Dla przykładu jeśli pole DPL danego segmentu ma wartość 0 wówczas jest adresowalne tylko dla programu z CPL rónymrównym 0 ( czyli działającego w trybie jądra). Jeśli DPL wynosi 3 wówczas rejestr jest dostpęnydostępny dla każdej wartości CPL (zarówno w trybie użytkownika jak i jądra).
*<font color ="green">P </font>- (ang. Semgnet-Present Flag) jeśli ta flaga jest równa 0 to dany segment nie jest w ogóle w pamięci operacyjnej, czyli jest odłożony na dysku twardym w postaci plikypliku wymiany ( za ten mechanizm odpowiada pamięć wirtualna).
*<font color ="green">D</font> lub <font color ="green">B</font> - flaga nazywana D lub w zależności od tego czy dany segment jest segmentem kodu czy danych. Znaczenie tego pola zależy ściśle od kontekstu w jakim został użyty.
**<font color="green">D</font> - Ta flaga w deskryptorze segmentu kodu mówi nam o "szerokości stosu". Jeśli flaga jest wyzerowana, szerokość stosu wynosi 16 bit (czyli ESP jest inkrementowany i dekrementowany o 2 bajty). Jeśli jest ustawiona na 1, szerokość wynosi 32 bity (analogicznie ESP rośnie lub maleje o 4 bajty).
Linia 38:
 
 
Co musi zrobić system operacyjny aby uzyskać adres liniowy z adresu logicznego ? Dla przykładu mamy wcześniejszy adres logiczny 0xc00d:1001. Najpierw brana jest część 0xC00D. IneksIndeks z selektora segmentu jest pomnożony przez 8 (ponieważ taką długość w bajtach ma deskryptor segmentu). Do tej liczby dodawana jest wartość Base z deskryptora segmentu. Odpowiedni Deskryptor segmentu system operacyjny bierze z GDT lub LDT a to zaś wybiera na podstawie wartości pola TI w selektorze. Po zsumowaniu na sam koniec dodawana jest wartość offsetu z naszego adresu logicznego czyli 0x1001.
Poniżej znajduje się rysunek pokazujący jak powstaje adres liniowy: