2009-11-17 25 views

Odpowiedz

37

Na 16-bit x86 segmentacji architektury pamięci, cztery rejestry są używane w odniesieniu do poszczególnych segmentów:

  • DS → segment danych
  • CS → segment kodu
  • segmentu SS → stos
  • ES → dodatkowym segmencie

adres logiczny na tej architekturze jest napisane segment:offset. Teraz, aby odpowiedzieć na pytanie:

  • Blisko wskaźniki odnoszą się (jako przesunięcie) do bieżącego segmentu.

  • Znaczące wskaźniki wykorzystują informacje o segmencie i przesunięcie do wskazywania segmentów. Aby ich użyć, DS lub CS muszą zostać zmienione na określoną wartość, pamięć zostanie dereferencjonowana, a następnie przywrócona zostanie oryginalna wartość DS/CS. Zauważ, że wskaźnik arytmetyczny na nich nie modyfikuje części segmentu wskaźnika, więc przepełnienie przesunięcia po prostu go zawinie.

  • A następnie są ogromne wskaźniki, które są znormalizowane, aby mieć najwyższy możliwy segment dla danego adresu (w przeciwieństwie do dalekich wskaźników).

W architekturach 32-bitowych i 64-bitowych modele pamięci używają segmentów inaczej lub wcale.

+3

Byłoby bardziej zrozumiałe, gdybyś wyjaśnił, co to jest segment (i przesunięcie w przypadku). "Segmenty" używane przez DOS są trochę tajemnicze, imho. – quark

21

Wskaźniki dalekie i bliskie były używane w starych platformach, takich jak DOS.

Nie sądzę, że są one istotne na nowoczesnych platformach. Ale możesz się o nich dowiedzieć here i here (jak wskazują inne odpowiedzi). Zasadniczo wskaźnik daleki jest sposobem na rozszerzenie adresowalnej pamięci w komputerze. I.E., adresują ponad 64 000 pamięci na platformie 16-bitowej.

+1

Wierzę, że niektóre systemy operacyjne mają dostęp do ponad 4 GB pamięci w systemie 32-bitowym. W takim przypadku konieczne są takie rozszerzone typy wskaźników. Jednak rzadko zdarza się, aby system operacyjny zezwalał aplikacjom trybu użytkownika na dostęp do ponad 4 GB w takim środowisku. –

+0

Tak. Dzieje się tak dlatego, że fizyczna szyna adresowa x86 ma szerokość 36 bitów dla komputerów 32-bitowych. Ale logiczna przestrzeń adresowa jest nadal ograniczona do 32 bitów. Rozszerzenia PAE udostępniają pamięć "extra" (w rzeczywistości za pomocą przełączania banków, IIRC). Prawdziwy problem polega na tym, że MMU jest trzymane mniej więcej (brak mmap, COW, itp.). Ale pamięć może być używana jako bufor dysku dla aplikacji, które same buforują. Lub system operacyjny, który obsługuje manipulację przełączaniem i MMU. – wildplasser

+0

PAE wykorzystuje dodatkowe bity w PTE MMU do adresowania czterech dodatkowych bitów informacji o ramce strony. Nie ma żadnego przejścia na moją wiedzę. –

3

Wskaźnik zasadniczo zawiera adresy. Jak wszyscy wiemy, zarządzanie pamięcią Intel jest podzielone na 4 segmenty. Tak więc, gdy adres wskazywany przez wskaźnik znajduje się w tym samym segmencie, jest to bliski wskaźnik i dlatego wymaga tylko 2 bajtów dla przesunięcia. Z drugiej strony, gdy wskaźnik wskazuje na adres znajdujący się poza segmentem (co oznacza, że ​​w innym segmencie), wskaźnik ten jest wskaźnikiem dalekim. Składa się z 4 bajtów: dwa dla segmentu i dwa dla przesunięcia.

+1

Witamy w StackOverflow. Kiedy kilka lat temu zobaczysz takie pytanie z zaakceptowaną odpowiedzią z dużą liczbą głosów upowych, z pewnością nadal możesz odpowiedzieć na to pytanie, ale możesz zebrać tylko głosy, jeśli odpowiedź jest dobrze napisana i dostarcza dokładnych nowych informacji, których nie zapewnia żadna z pozostałych odpowiedzi. Nie jestem pewien, czy twoja odpowiedź spełnia ten standard. –

+0

"Zarządzanie pamięcią Intel jest podzielone na 4 segmenty"? Mogą istnieć 4 rejestry segmentowe (nie jestem pewien), ale istnieje wiele więcej niż 4 segmenty. Tak naprawdę nie wyjaśniłeś, jak to działa w 16-bitowym systemie, w którym konieczne były segmenty i przesunięcia. Powinieneś wtedy objąć systemy 32-bitowe i wspomnieć, czy systemy 64-bitowe mają jakąkolwiek istotnie inną (w przeciwieństwie do większych) charakterystykę. –

0

Cztery rejestry są używane w odniesieniu do czterech segmentów w 16-bitowej architekturze pamięci segmentowej x86. DS (segment danych), CS (segment kodu), SS (segment stosu) i ES (dodatkowy segment). Adres logiczny na tej platformie jest zapisany w segmencie: offset, w systemie szesnastkowym.

Zbliżone wskaźniki odnoszą się (jako przesunięcie) do bieżącego segmentu.

Znaczące wskaźniki wykorzystują informacje o segmencie i przesunięcie do wskazywania segmentów. Aby ich użyć, DS lub CS muszą zostać zmienione na określoną wartość, pamięć zostanie dereferencjonowana, a następnie przywrócona zostanie oryginalna wartość DS/CS.Zauważ, że wskaźnik arytmetyczny na nich nie modyfikuje części segmentu wskaźnika, więc przepełnienie przesunięcia po prostu ją zawinie.

A następnie są ogromne wskaźniki, które są znormalizowane, aby mieć najwyższy możliwy segment dla danego adresu (w przeciwieństwie do daleko wskazujących).

W architekturach 32-bitowych i 64-bitowych modele pamięci używają segmentów inaczej lub wcale.

+0

Te rejestry są rzeczywiście używane do różnych celów. Jak wspomniałeś sam siebie, rejestry KODÓW, DANYCH, STAKÓW, EXTRA. Oczywiście są też AX, BX, DX, CX. Ale CS był dla CODE, DS dla DATA, SS dla Stack i ES - dla rozszerzenia istniejących danych i zmiennych kodowych. AX/BX/CX/DX w czasach DOS był bardzo ważny. Jak każdy inny rejestr. Kiedy wywołano funkcje przerwań (INT), wiele z nich polegało na rzeczywistych wartościach rejestru. –

0

Cóż, w DOS było to zabawne w kontaktach z rejestrami. I segmenty. Wszystko o maksymalnych możliwościach liczenia pamięci RAM.

Dziś nie ma to większego znaczenia. Wszystko, co musisz przeczytać, to różnica w przestrzeni wirtualnej/użytkownika i jądrze.

Od wygrania nt4 (kiedy ukradli pomysły z * nix) programiści Microsoftu zaczęli używać tak zwanych przestrzeni pamięci użytkownika/jądra. I od tego czasu unikałem bezpośredniego dostępu do kontrolerów fizycznych. Odtąd rozwiązano problem związany z bezpośrednim dostępem do segmentów pamięci. - Wszystko stało się R/W przez OS.

Jednakże, jeśli nalegasz na zrozumienie i manipulowanie dalekimi/bliskimi wskaźnikami, spójrz na źródło jądra Linuksa i jak działa - prawdopodobnie powrócisz.

A jeśli nadal potrzebujesz używać CS (Segment kodu)/DS (Segment danych) w DOS. Spójrz na nich:

https://en.wikipedia.org/wiki/Intel_Memory_Model http://www.digitalmars.com/ctg/ctgMemoryModel.html

Chciałbym zwrócić uwagę doskonałą odpowiedzią poniżej .. od Lundin. Byłem zbyt leniwy, by odpowiedzieć poprawnie. Lundin dał bardzo szczegółowe i sensowne wytłumaczenie "kciuk w górę"!

20

Ponieważ nikt nie wspomniał o DOS, pozwala zapomnieć o starych komputerach PC DOS i spojrzeć na to z ogólnego punktu widzenia. Następnie bardzo uproszczona, to idzie tak:


Każdy procesor ma szynę danych, która jest maksymalna ilość danych, procesor może przetwarzać w jednej instrukcji, tj równa wielkości swoich rejestrach. Szerokość magistrali danych wyrażana jest w bitach: 8 bitach, 16 bitach lub 64 bitach itd. Tu powstaje termin "64 bitowy procesor" - odnosi się do magistrali danych.

Każdy procesor ma magistralę adresową, również o określonej szerokości magistrali wyrażonej w bitach. Każda komórka pamięci w komputerze, do której procesor ma bezpośredni dostęp, ma unikalny adres. Magistrala adresowa jest wystarczająco duża, aby objąć całą adresowalną pamięć, którą posiadasz.

Na przykład, jeśli komputer ma 65536 bajtów pamięci adresowalnych można pokryć je z adresem 16 bitowej magistrali, 2^16 = 65536.

najczęściej, ale nie zawsze, szerokość magistrali danych tak szeroki, jak szerokość szyny adresowej. Fajnie, jeśli są one tego samego rozmiaru, ponieważ utrzymuje zarówno instrukcję zestawu CPU, jak i programy napisane dla niego jaśniej. Jeśli procesor musi obliczyć adres, wygodnie jest, jeśli ten adres jest wystarczająco mały, aby zmieścić się w rejestrach procesora (często nazywanych rejestrami indeksu, jeśli chodzi o adresy).

Te nietypowe słowa kluczowe far i near są używane do opisania wskaźników w systemach, gdzie trzeba adresować pamięć poza normalnym adresowej procesora szerokości magistrali.

Na przykład wygodnie jest, jeśli procesor z 16-bitową magistralą danych ma 16-bitową magistralę adresową. Ale ten sam komputer może również potrzebować więcej niż 2^16 = 65536 bajtów = 64kb adresowalnej pamięci.

Procesor będzie zazwyczaj miał specjalne instrukcje (które są nieco wolniejsze), co pozwala adresować pamięć poza te 64 kb. Na przykład, CPU może podzielić swoją dużą pamięć do nstron (zwany też czasami banki, segmenty i inne takie terminy, które mogą oznaczać różne rzeczy z jednego procesora do drugiego), gdzie każda strona jest 64kb. Będzie wtedy miał rejestr "strony", który musi zostać ustawiony jako pierwszy, zanim zajmie się tą rozszerzoną pamięcią. Podobnie będzie miała specjalne instrukcje podczas wywoływania/powracania z podprogramów w pamięci rozszerzonej.

Aby kompilator języka C wygenerował poprawne instrukcje dotyczące procesora podczas pracy z taką rozszerzoną pamięcią, wymyślono niestandardowe słowa kluczowe: near i far. Niestandardowe, ponieważ nie są określone przez standard C, ale są de facto standardem branżowym i prawie każdy kompilator obsługuje je w jakiś sposób.

far odnosi się do pamięci znajdującej się w pamięci rozszerzonej, poza szerokość szyny adresowej. Ponieważ odnosi się do adresów, najczęściej używa się go podczas deklarowania wskaźników. Na przykład: int * far x; oznacza "podaj mi wskaźnik, który wskazuje na rozszerzoną pamięć". Kompilator będzie wówczas wiedział, że powinien wygenerować specjalne instrukcje potrzebne do uzyskania dostępu do takiej pamięci. Podobnie, wskaźniki funkcyjne, które używają far wygenerują specjalne instrukcje, aby przejść do/powrócić z pamięci rozszerzonej. Jeśli nie użyjesz far, dostaniesz wskaźnik do normalnej, adresowalnej pamięci, a skończysz wskazując na coś zupełnie innego.

near jest zawarty głównie w celu zachowania spójności z far; odnosi się do wszystkiego w adresowalnej pamięci, co jest odpowiednikiem zwykłego wskaźnika. Jest to więc głównie bezużyteczne słowo kluczowe, z wyjątkiem rzadkich przypadków, w których chcesz się upewnić, że kod znajduje się w standardowej adresowalnej pamięci. Możesz wtedy wyraźnie oznaczyć coś jako near. Najbardziej typowym przypadkiem jest programowanie sprzętowe niskiego poziomu, w którym piszemy procedury obsługi przerwań. Są one wywoływane przez sprzęt z wektora przerwań o stałej szerokości, która jest taka sama jak szerokość szyny adresowej. Oznacza to, że procedura obsługi przerwania musi znajdować się w standardowej adresowalnej pamięci.


Najsłynniejszy wykorzystanie far i near jest chyba wymienić stary MS DOS PC, który jest obecnie uważany za dość stara i dlatego z umiarkowanym zainteresowaniem.

Ale te słowa kluczowe istnieją również w bardziej nowoczesnych procesorach! Przede wszystkim w systemach wbudowanych, w których istnieją prawie wszystkie 8 i 16-bitowe rodziny mikrokontrolerów na rynku, ponieważ te mikrokontrolery mają zwykle szerokość magistrali adresowej 16 bitów, ale czasami więcej niż 64kb pamięci.

Ilekroć masz procesor, w którym musisz zaadresować pamięć poza szerokość szyny adresowej, będziesz potrzebował far i near. Zasadniczo takie rozwiązania są jednak źle postrzegane, ponieważ programowanie ich jest dość trudne i zawsze bierze pod uwagę rozszerzoną pamięć.

Jednym z głównych powodów, dla których nastąpił impuls do rozwoju komputera 64-bitowego, było to, że komputery 32-bitowe doszły do ​​punktu, w którym ich użycie pamięci zaczęło osiągać limit magistrali adresowej: mogły one tylko adresować 4 GB pamięci RAM. 2^32 = 4,29 miliarda bajtów = 4 Gb. Aby umożliwić korzystanie z większej ilości pamięci RAM, opcje polegały albo na uciekaniu się do jakiegoś uciążliwego rozszerzonego rozwiązania pamięciowego, jak w dniach DOS, albo na rozszerzeniu komputerów, w tym ich magistrali adresowej, na 64 bity.

+0

Świetna odpowiedź! Bardzo informujące. –

+0

"używane do opisu wskaźników w systemach, w których musisz zaadresować pamięć poza zwykłą szerokość magistrali adresowej procesora" - nie, 8086 miał 20-bitową magistralę adresową. Segmentacja pamięci polegała na generowaniu szerszych adresów bez powiększania rozmiaru wskaźnika. "Tu pochodzi określenie" 64-bitowy procesor "- odnosi się do magistrali danych." - nie, odnosi się do szerokości rejestru całkowitoliczbowego. Magistrale danych są zwykle szersze, z pamięcią podręczną L1 zdolną do ładowania rejestru SIMD o 128 bitach, a wyższe poziomy hierarchii pamięci są jeszcze szersze. Szyny adresów są zwykle węższe; MMU może nie mieć 64-bitowej fizycznej przestrzeni adresowej. – Potatoswatter

Powiązane problemy