2012-06-17 14 views
15

Po prostu tego nie rozumiem. Każda instrukcja jest zbyt techniczna. Co to jest pamięć płaska i podzielona na segmenty? Sposoby adresowania pamięci, sposoby porządkowania bajtów w pamięci? Który z nich jest najlepszy dla komputerów 32-bitowych? Czy ktoś może to wyjaśnić? Co ma wspólnego z trybem rzeczywistym i trybem chronionym z pamięcią płaską lub segmentową? Dzięki!PAMIĘĆ SEGMENTOWA vs PŁASKA PAMIĘĆ

+3

segmentowe pamięci (w 32 i 64-bitowych gruntu) trzymać się od chwili, gdy wymagania dotyczące pamięci przekroczyła wielkość autobusu adresowego. Takie rozważania już dawno przeszły i wszyscy teraz używają płaskiego modelu. Projektanci Motorola 68K (znacznie lepszy procesor (o wiele bardziej elegancki zestaw instrukcji) do 286 i to poprzednicy) wiedział o tym i nie przeszkadzało z segmentową adresowania. Ale historia nie dba o estetykę i Intel wygrał, a teraz wszyscy używamy potomków 386. –

Odpowiedz

18

Jeśli interesują cię tylko aplikacje działające na istniejących systemach operacyjnych o 32 bitach na 64 bity, możesz po prostu zapomnieć o pamięci segmentowanej. W systemach 32-bitowych można założyć, że masz 4 GB "płaskiej" pamięci. Płaskie oznacza, że ​​możesz manipulować adresami z wartościami i rejestrami 32-bitowymi, jak można się spodziewać.

Na procesorach 16-bitowych uważam, że adres miał szerokość 20 bitów i nie można było tego zapisać w rejestrze, więc trzeba było przechowywać bazę w jednym rejestrze, a w celu określenia faktycznego adresu trzeba było dodaj przesunięcie do tej podstawy. (Jeśli dobrze pamiętam, podstawa została pomnożona przez 16, to przesunięcie zostało dodane, aby uzyskać aktualny adres.) Oznacza to, że możesz tylko adresować 64 kB na raz; pamięć musiała być "podzielona na segmenty" w blokach 64 KB.

Szczerze mówiąc, myślę, że jedynym powodem, dla którego początkujący o tym słyszą, jest to, że wiele starych 16-bitowych samouczków i książek nadal jest dostępnych. Naprawdę nie trzeba rozumieć, jak program działa na poziomie zespołu. Teraz, jeśli chcesz nauczyć się rozwoju systemu operacyjnego, to już inna historia. Ponieważ komputer uruchamia się w trybie 16-bitowym, musisz nauczyć się przynajmniej na tyle, aby móc aktywować płaski tryb 32-bitowy.

Właśnie zauważyłem, że pytasz także o tryb rzeczywisty a tryb chroniony. Tryb Real jest trybem używanym przez MS DOS. Każdy program miał dostęp do dowolnej funkcji sprzętowej, na przykład często było rozmawiać bezpośrednio z kontrolerem karty graficznej, aby coś wydrukować. Nie spowodowało żadnego problemu, ponieważ nie było wielozadaniowym systemem operacyjnym.

Jednak w przypadku każdego nowoczesnego systemu operacyjnego normalne programy nie uzyskują bezpośredniego dostępu do sprzętu, nie mają nawet bezpośredniego dostępu do pamięci. System operacyjny zarządza sprzętem i decyduje, który proces zostanie uruchomiony na procesorze (-ach). Zarządza również wirtualną przestrzenią adresową dla każdego procesu. Ten rodzaj funkcji jest dostępny w trybie chronionym, który moim zdaniem pochodzi z 386, który był pierwszym 32-bitowym procesorem na PC.

+0

+1, aby uzyskać szczegółową odpowiedź! –

+0

Segmentowanie adresowania pamięci jest jak formuła, która pasuje do rejestru 16 bitów i określa adres z pamięci, która jest większa niż pojemność rejestru. Komputer startuje w 16-bitowym trybie adresowania, co oznacza, że ​​BIOS nie może odczytać 32-bitowego adresu? Dzięki! – ali

+0

@ali: Nie wiem, jak zaimplementowano BIOS.Technicznie rzecz biorąc, domyślam się, że nic nie uniemożliwia BIOSowi przejścia na 32 bity, a następnie wraca do 16 bitów, jeśli naprawdę jest potrzebny z jakiegoś powodu. –

8

Instrukcje, które uzyskują dostęp do czegoś za pomocą adresu (pamięć, we/wy, odwzorowane w pamięci wejścia/wyjścia, itp.) Czasami dostarczają kompletnego (z perspektywy tej warstwy wykonania procesora) adresu, czasami zapewniają przesunięcie. Twoje skoki bliskie lub względne, na przykład licznik programu, to adres bazowy, a instrukcja zapewnia przesunięcie do tej podstawy, dodaj dwa razem i otrzymasz adres (na tym poziomie).

Weź 16-bitowy system, w którym masz 16-bitowe rejestry i maksymalny 64-bajtowy limit przestrzeni adresowej. Bardzo prostym sposobem na rozszerzenie tej pamięci jest segmentacja. Zamiast rejestru zawierającego cały adres, rejestr w twojej instrukcji zawiera przesunięcie do bazy, podobnie jak instrukcja względna. Z wyjątkiem tego przypadku istnieje jeszcze inny rejestr, który jest używany jako adres bazowy. Widać to w wielu architekturach, które chciały łatwo rozszerzyć zakres adresów bez zbytniego modyfikowania rdzenia. (można to zrobić w kontrolerze pamięci bez modyfikacji do rdzenia) W przypadku x86 było kilka rejestrów. Jeden został użyty do rozszerzenia zasięgu egzekucji, oddziałów. Kolejne rozszerzenie zasięgu dostępu do danych, ładunków i sklepów. Adres niepochodzącej od komputera gałęzi został obliczony przy użyciu przesuniętego lewego 4-bitowego segmentu kodu, a następnie dodanego do rejestru określonego w instrukcji. W przypadku obciążeń i sklepów, które nie są zależne od komputera, zastosowano rejestr segmentów danych, przesunięcie w lewo 4 dodaje rejestr podany w instrukcji. więc jeśli chcesz adresować 0x123456789, możesz mieć rejestr segmentu zawierający 0x12340000, a rejestr użyty do adresowania zawiera 0x56789 lub segment 0x12345678, a gpr zawiera 0x9. Adresacja względna Pc to oczywiście segment + pc + offset.

To prowadzi do przyjęcia różnych modeli pamięci. małe, małe, średnie, duże, ogromne. Można sobie wyobrazić, że najmniejszy model będzie miał regułę lub założy w przypadku x86, że wszystko znajduje się w przestrzeni pamięci 64K, kompilator i twój kod nigdy nie muszą martwić się o rejestry segmentów, zakłada się, że są one stałe. W przypadku większych modeli lub w przypadku korzystania z dalekiego wskaźnika sięgającego dalej nie ma większego problemu, należy ustawić segment danych, a następnie ustawić przesunięcie danych i wykonać ładowanie lub magazynowanie. Dla kodu można to sobie wyobrazić nieco trudniej, ponieważ zaraz po zmianie rejestru segmentu kodu wpływa on na ogólny adres, z którego pobierane są instrukcje. Możesz chcieć rozwiązania sprzętowego, aby gałąź mogła zmodyfikować zarówno segment, jak i offset, lub możesz to zrobić w kodzie (jeśli sprzęt jest dozwolony). Na razie nie pomylę cię z tym.

Gdy masz tablicę w postaci kodu:

unsigned char abc[123]; 

który jest w zasadzie taka sama. Adres bazowy, adres, w którym tablica zaczyna się w pamięci, przypomina segment, a indeks jest twoim przesunięciem. Jeśli w powyższym abc był pod adresem 0x1004, abc [5] znajduje się pod adresem 0x1004 + 5 = 0x1009. Nie przesunięty jak segment x86: adresowanie offsetowe, ale ta sama koncepcja dodawania bazy i offsetu. Niektóre segmentowane architektury, które nie mają dodatku, niektóre bity w niektórych rejestrach gdzieś są górnymi bitami. Weź adres 0x12345 na jednym z tych systemów 0x1 musi znajdować się w segmencie, a 0x2345 w 16-bitowym gpr. Możesz myśleć o tym jako o przesunięciu i dodawać, jeśli chcesz, ale w odróżnieniu od segmentu x86: offset możesz również myśleć o nim jako o przesunięciu i lub.

Płaska przestrzeń pamięci jest odrobiną iluzji, szczególnie w systemach x86. Komputery x86, 32-bitowe, a nawet 64-bitowe, ograniczają ilość płaskiej pamięci do włożenia kart w sumie 1Gig, co ma sens w 32-bitowym systemie, w którym masz 4 gigabajty przestrzeni adresowej, oraz dlatego niektóre z nich dają limit 3 gigów lub dają iluzję 4 koncertów, ale niektóre z nich zostały przeznaczył na podłączenie kart. (wiele z twoich pozycji na płycie głównej znajduje się w tym miejscu, a także w rzeczywistej wtyczce do kart). W zależności od karty graficznej i rozdzielczości itp. Czasami nie można dopasować całego bufora ramki w podzbiorze tej przestrzeni peryferyjnej, więc musisz podzielić swój dostęp. bios mógł podać adres 0x80000000 jako bazę w przestrzeni adresowej x86, a następnie w innym rejestrze na karcie wideo określić adres w przestrzeni adresowej karty wideo. dla celów demonstracyjnych powiedzmy, że otrzymałeś 16 MB okna na adres x86 0x80000000. 16 MB to 0x01000000. jeśli chcesz uzyskać dostęp do adresu 0x04321888 w pamięci wideo, możesz sobie wyobrazić, że musisz ustawić rejestr segmentów na karcie graficznej na 0x04, a następnie w przestrzeni adresowej x86 (która jest również przestrzenią adresową pci (e)) użyj adresu 0x80321888.

Najważniejsze jest tutaj pobranie niektórych bitów i niektórych bitów, złożyć je razem i jest to adres docelowy. Podczas pracy z urządzeniami peryferyjnymi, czy to kartą wideo, czy kontrolerami wejścia/wyjścia na płycie, lub kontrolerem pci lub pcie, musisz nauczyć się myśleć w kategoriach przestrzeni adresowej celów. procesor ma przestrzeń adresową z perspektywy twojego programu. Mmu może i robi to w fizycznej przestrzeni adresowej, wtedy masz swoją przestrzeń adresową pcie, a następnie urządzenia peryferyjne dostępne poprzez pcie mają swoją własną przestrzeń adresową. To, co zrobił komputer intel i intel-pc, sprawiło, że fizyczna przestrzeń adresowa procesorów i przestrzeń adresowa pcie były takie same. Wirtualne vs fizyczne szyfrowanie w mmu nadal istnieje, a okno do przestrzeni adresowej urządzeń peryferyjnych nadal tam jest, nadal musisz pobrać trochę adresu stąd i trochę stamtąd, aby uzyskać końcowy adres w dowolnym celu.

Prawdziwy i chroniony ma do niego dostęp. Na przykład w języku C można tworzyć wskaźniki, zmieniać wskaźniki i tworzyć dowolne adresy, czy nie oznacza to, że można przechwytywać w innej pamięci aplikacji lub pamięci jądra?Idealnie nie chcesz, aby tak się stało, więc dla każdej aplikacji, gdy wykonujesz instrukcje dla tej aplikacji, jesteś w odrobinie maszyny wirtualnej, każdy dostęp do pamięci to jej kod lub instrukcja przechodzi przez filtr, jeśli zechcesz. Ten filtr sprawdza, czy ten dostęp znajduje się w dozwolonej przestrzeni programu, jeśli wyjdzie poza to miejsce, nastąpi wyjątek (myśl przerwanie), że wyjątek zezwala na jądro (które nie ma tych ograniczeń lub ma inne ograniczenia), aby zezwolić na dostęp lub może zwirtualizować dostęp do czegoś lub wygenerować ostrzeżenie dla użytkownika (ogólny błąd ochrony). Weźmy na przykład rzeczywisty program maszyny wirtualnej, taki jak vmware, zezwalaj zwirtualizowanemu programowi faktycznie uruchamiać instrukcje na procesorze, gdy ten zwirtualizowany program uzyskuje dostęp do adresu karty graficznej, pojawia się błąd ochrony, sterownik vmware/aplikacja (Myślę, że poziom jądra) przyjmuje ten adres i podrabia odpowiedź karty wideo i zwraca kontrolę do aplikacji. Uruchamianie instrukcji na metalu pozwala na znacznie szybszą wirtualizację na alternatywę, która polega na symulacji każdej instrukcji procesora. To jest skrajny przypadek, nawet przeglądarka, na której czytasz to zostało zwirtualizowane, więc uważa, że ​​ma przestrzeń pamięci opartą na jakimś bazowym adresie, takim jak 0x000 lub 0x8000, kompilujesz każdy program dla konkretnego systemu operacyjnego do tego samego. płaska wirtualna pamięć i system operacyjny dba o zmianę adresów z wirtualnego na fizyczny. Twój przeglądarkę internetową dostęp do jej adresu 0x8000 może być fizyczny 0x12345678, a twój dostęp do odtwarzaczy mp3 0x8000 może być fizyczny 0x2345678, ale do obu aplikacji ich instrukcje obliczają 0x8000.

pytając, co jest najlepsze jest zawsze pojęciem względnym, jeden osoby najlepiej jest kolejne osoby najgorsze. Musisz samemu określić najlepszy z najgorszych. Momentum i opinia publiczna popchnęły x86 do płaskiej przestrzeni pamięci lub przynajmniej iluzji płaskiej przestrzeni pamięci z perspektywy programistów, więc będziesz miał mniej kłopotów z przepływem.

Polecam uzyskać kopię 8086/8088 programistów i instrukcję obsługi sprzętu, można mieć za kilka dolców.

http://www.amazon.com/Manual-Programmers-Hardware-Reference-240487-001/dp/1555120814/ref=sr_1_1?ie=UTF8&qid=1340000636&sr=8-1&keywords=8088+programmers+reference

Take symulator jak pcemu (mam klona do tego celu http://github.com/dwelch67/pcemu_samples) i bawić się z zestawu instrukcji, starą szkołę dobrze przed wirtualizacji, ochrony itp Powrót kiedy trzeba było segmentów i przesunięcia obliczone jako wspomniano powyżej, przesuń segment po lewej cztery i dodaj przesunięcie (co jest opisane w tej instrukcji). Każde pokolenie, odkąd zrobiło coś, aby spróbować poprawić, starając się być kompatybilne odwrotnie. Co oczywiście pomogło zyskom, ale zamieniło procesory w paskudne bestie. Lepiej zapomnij o szczegółach x86 i naucz się czystszych systemów, ponieważ ewolucja x86 przyniosła minimalne zyski, na przykład próbując napisać coś w asmie nad skompilowanym kodem. Ponieważ procesory z różnych rodzin wykonują ten sam kod przy różnych prędkościach, często nowa generacja wykonuje ręcznie dostrojony kod z poprzedniego w znacznie wolniejszym tempie. Nie możesz ręcznie dostroić czegoś, aby było szybkie na wszystkich platformach, nie szybciej niż kompilator, więc po prostu zostaw kod kompilatora x86 kompilatorom. Prace przy rozsądnych platformach gdzie nie masz te problemy i można dostroić, jeśli chcesz lub dokonać lepszego kompilatora itp

Powiązane problemy