Elektroda.pl
Elektroda.pl
X
PCBway
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Segmenty pamięci - jak je sobie wyobrazić?

08 Paź 2012 17:35 2403 14
  • Poziom 11  
    Witam was serdecznie, otóż poznaje dla nauki architekturę procesora, no i ustałem na segmentach pamięci w trybie rzeczywistym. Nie mam pojęcia jak je sobie wyobraźić, ani jak się do nich odwoływać. Wiem, że jest ich 16 i mają po 64kB, no ale o co chodzi z tym segmentem i offsetem, jak w nich cokolwiek umieszczać, skąd mam wiedzieć gdzie co jest no i tutaj mam coś takiego:
    Code:

    0x00000000 - 0x000003FF        - tablica wektorow przerwan
    0x00000400 - 0x000004FF        - BDA przestrzen danych biosu
    0x00000500 - 0x00007BFF        - wolna, dostepna pamiec
    0x00007C00 - 0x00007DFF        - miejsce na bootloader
    0x00007E00 - 0x0007FFFF        - wolna, dostepna pamiec
    0x00080000 - 0x0009FBFF        - wolna, dostepna pamiec, jesli istnieje
    0x0009FC00 - 0x0009FFFF        - EBDA rozszerzona przestzen danych biosu
    -----------------------        -------------------------------------------
    0x0000A000 : 0x00000000        - pamiec video karty VGA
    0x0000B000 : 0x00000000        - pamiec video karty Hercules Monochrome
    0x0000B800 : 0x00000000        - pamiec trybu tekstowego karty VGA


    Segmentów powinno być 16, tu jest inaczej. Jeżeli nie nauczę się adresować pamięci i odwoływać się do niej, to nigdy nie poznam architektury procesora 386, więc jak mam sobie wyobraźić te segmenty, jak z nich korzystać i o co w nich wogóle chodzi? Najlepiej, żeby odpowiedź była dokładnie wyjaśniona i podparta jakimś prostym przykładem w Asmie.
  • PCBway
  • Poziom 42  
    Adres = 16 * segment + offset. Czyli dla zapisu szesnastkowego, do adresu segmentu dodaje się 0 na końcu, następnie sumuje z offsetem i dostaje adres pamięci. Ot, cała filozofia.

    Tak więc zapis 0000:7C00 to to samo co 0700:0C00 i to samo co o7C0:0000
  • PCBway
  • Poziom 32  
    Zapomnij o tym, to stary intelowski wynalazek, do niczego nie przydatny. Jakies 20 lat temu, jak śp J. Bielecki prowadził wykłady z C od razu powiedzial, by te "modele pamieci" z Borland C sobie olać, bo to tylko jakaś przejściowa łata na ograniczenia procesora 8086. Od 386 pod windą, linuxem itp masz po prostu 32bitowe liniowe adresowanie.
  • Poziom 23  
    Witam!
    Myślę, że Kolega Dżyszla wyjaśnił w wystarczającym stopniu, ale popróbuj instrukcji LEA w asemblerze i przeanalizowaniu w debuggerze

    Dodano po 15 [minuty]:

    Witam!
    Do Kolegi krru...
    Przykro mi słyszeć, że Pan Jan Bielecki już Ś.P. Mam w swojej bibliotece do dzisiaj kilka Jego książek (poprawianych przeze mnie na marginesie). Miałem również zaszczyt polemizować z Nim, jako skromny pracownik WZE ELWRO, nad pewnymi odmianami kompilatorów napisanymi na procesory ośmiobitowe np HisoftC...
    Jednak nadmieniam, że po windą i linuksem, te procesory przechodzą w tryb wirtualny w którym adresacja jest 32-bitowa w trybie chronionym, a Kolega Bingo009 zapytał o segmentację, czyli TRYB RZECZYWISTY, a to przecież co innego...
  • Poziom 11  
    Problem w tym, że ja nie mogę zapomnieć, bo uczę się obsługiwać procesor na bardzo niskim poziomie. Czyli w skrócie jak działa jądro systemu. Więc nie mogę o tym zapomnieć, bo skoro chcę nauczyć się działania procesorów Intela, to muszę poznać tryb rzeczywisty. Jako praktykę piszę kernela w Asmie, co pozwala mi o wiele lepiej zrozumieć jak to faktycznie działa. Ale co z tymi adresami? Jest ich 16, czy ile? Dalej za bardzo nie kumam. Przydałoby się jakieś wyobrażenie. A co z tym co podałem? To adresy fizyczne czy co? Nie powinno ich być 16? O co w tym chodzi? Tyle pytań, a tak mało mojej wiedzy, ale mam czas na naukę. Wiem, że tryb rzeczywisty to przestarzałość już jest, ale uwierz mi, jestem świadomy co chcę umieć, więc proszę o odpowiedź.
  • Poziom 42  
    Adresów masz tyle, ile potrafisz zaadresować, czyli de facto dla 16-adresowania w trybie rzeczywistym - 1MB (to właśnie wynika z 16 segmentów, czyli efektywnie 20-bitowego adresowania pamięci). Segmentów z kolei w trybie adresowania jest FFFFh, a każdy z nich może mieć maksymalnie FFFFh ofsetów, z tym że pomiędzy segmentami jest różnica tylko Fh bajtów. Jednak Intel (albo IBM?) przyjął podział pamięci na 16 segmentów (czyli każdy odległy o 10000h bajtów), a więc w notacji segment:ofset - 1000:0000 - a więc standardowo:
    segment I: 0000:0000 do 0000:FFFF
    segment II: 1000:0000 do 1000:FFFF
    itd, czyli wartościowo:
    segment I: 00000h do 0FFFFh
    segment II: 10000h do 1FFFFh

    Jednak zapisując program możesz tworzyć dowolne kombinacje segment:offset zgodnie z podanym przeze mnie wzorem na początku - masz 2^3 sposobów zapisu tego samego adresu.
  • Poziom 23  
    Witam!

    W muzealnym procku INTEL 80386 jest sześć rejestrów segmentowych:

    CS - rejestr segmentowy rozkazów stowarzyszony z licznikiem rozkazów
    SS - rejestr segmentowy stosu, stowarzyszony ze wskaźnikiem stosu
    DS - rejestr segmentowy danych, stowarzyszony z adresem danych
    ES - rejestr segmentowy dodatkowy 1 stowarzyszony z adresem danych
    FS - rejestr segmentowy dodatkowy 2 stowarzyszony z adresem danych
    GS - rejestr segmentowy dodatkowy 3 stowarzyszony z adresem danych

    I inne rejestry:
    EAX - akumulator
    EBX - rejestr bazowy
    ECX - rejestr licznikowy
    EDX - rejestr danych

    CP - licznik rozkazów
    ESP - wskaźnik stosu
    EBP - wskaźnik bazy
    ESI - rejestr indeksowy źródła
    EDI - rejestr indeksowy danych

    itd.

    Wszystkie rejestry w intelu 8086 (tak, cofniemy się do tego muzealnego egzemplarza aby lepiej wytłumaczyć)
    są 16-bitowe, a przestrzeń adresowa jest 20-bitowa.
    Jak zatem z tych 16 bitów uzyskać 20 ?


    Załóżmy, że dana umieszczona jest pod adresem 00101 w przestrzeni adresowej kompa a odwołujesz się do niej za pośrednictwem rejestru segmentowego danych DS i rejestru BX.

    W rejestrze segmentowym DS umieszczona jest zawartość np 0010, a do BX wpisujemy 0001.

    Adres efektywny tej komórki obliczony jest w sposób następujący:
    Zawartość właściwego rejestru segmentowego mnożona jest przez 16, innymi słowy:

    zawartość jest przesuwana w lewo o 4 bity. Uzyskujemy w ten sposób:
    00100

    Do tak spreparowanej wartości dodajemy zawartość BX (czyli 0001) i uzyskujemy w ten

    sposób adres efektywny 00101.

    Lub DS = 0001
    Po przesunięciu w prawo o 4 bity DS otrzymujemy:
    00010
    Wówczas chcąc uzyskać adres efektywny 00101 musimy do rejestru BX wpisać: 0011
    żeby po zsumowaniu przesuniętej zawartości DS i BX uzyskać adres efektywny 00101

    I tak można kombinować z pozostałymi rejestrami segmentowymi i roboczymi.

    Reasumując, musisz pamiętać o zawartości rejestru segmentowego zanim wpiszesz adres do rejestru np BP. Oczywiście, jeśli zawartość odpowiedniego rejestru segmentowego wynosi 0000, to do BP wpisujesz adres efektywny, w przeciwnym wypadku musisz dokonać korekty czy to w rejestrze segmentowym, czy roboczym.

    W asemblerze do obliczenia adresu efektywnego służy instrukcja LEA (ładuj adres efektywny), która do rejestru roboczego wpisuje adres skorygowany pod względem zawartości odpowiedniego rejestru segmentowego
  • Użytkownik usunął konto  
  • Poziom 11  
    Właśnie piszę swój MBR, na początku miałem użyć GRUB'a, ale uznałem, że to marny pomysł, mało się nauczę i GRUB odrazu przechodzi do Protected Mode, który jak narazie jest dla mnie ciemną magią. Wiem, że można GRUBA skonfigurować tak, aby nie przechodził do PMode, ale uznałem, że nie warto się babrać i zabrałem się za pisanie własnego. Myślę, że rozumiem o co biega już, chodzi o to, że sam tworzę sobie segmenty na podstawie adresu i offsetu w tych rejestrach. A dałoby radę jakiś prosty przykład, jak się odwoływać do takiego segmentu?
  • Poziom 23  
    Witam!
    Modyfikować i pobierać zawartości wszystkich rejestrów segmentowych można normalnie, instrukcjami MOV, PUSH/POP itd.
    np: MOV AX,DS (rejestr segmentowy danych do rejestru AX), PUSH SI/POP AX (do AX ładujesz zawartość rejestru segmentowego SI)
    Co do rejestru segmentowego CS (rejestr segmentowy rozkazów) to oprócz powyższych instrukcji, można ich zawartość modyfikować za posrednictwem skoku dalekiego (JMP FAR), lub skoku ze śladem dalekiego (CALL FAR) z tym, że powrót też musi być "daleki" (RETF)

    Dalej:
    Jak wspomniałem w swoim poprzednim poście rejestry segmentowe są przypisane poszczególnym grupom:
    CS - licznikowi rozkazów
    SS - wskaźnikowi stosu
    DS - dane
    ES - dodatkowy segment danych
    FS - j.w.
    GS - j.w.
    zatem:
    - przy instrukcjach skoków procesor domyślnie korzystac będzie z rejestru segmentowego CS
    - przy odwołaniu sie do operacji związanych ze stosem, procesor domyślnie korzystać będzie z rejestru segmentowego SS
    - przy odwoływaniu się do danych, procesor domyślnie będzie korzystać z rejestru segmentowego DS

    Ale jeśli dostęp do danych ma być podparty rejestrem segmentowym innym niż DS, np ES, to wtedy dany adres należy poprzedzić jawną nazwą własciwego rejestru segmentowego zakończoną dwukropkiem.
    Przykład: do rejestru AX chcesz przesłać zawartość komórki pamięci adres której umieszczony jest w rejestrze SI a segment umieszczony jest w ES, to zapis wygląda tak:
    Kod: asm
    Zaloguj się, aby zobaczyć kod

    Pamiętaj tylko, że wyprodukowany przez asembler kod tej instrukcji będzie wiekszy o 1 bajt.
  • Poziom 11  
    Dobra, podsumujmy to co umiem. Tutaj kawałek mapy pamięci w Real Mode:
    Code:

    0x1000:0x0000-0x9000:0xFFFF - pamięć użytkownika


    Czyli idać tym tropem mam do zagospodarowania 8 segmentów(zgodnie ze specyfikacją Real Mode każdy po 64kb), a offset to tak jakby wskaźnić na dokładne miejsce w pamięci. I poprostu sobie to przeliczam na adres fizyczny i mogę się dowolnie odwoływać to tego? Z tego co tu patrzę to powininenem mieć do wykorzystania 512kb(8 segmentów po 64kb każdy). No dobra, czyli obrazowo można to pokazać tak:
    Segmenty pamięci - jak je sobie wyobrazić?
  • Poziom 33  
    antekone napisał:
    Przeglądałeś książkę "Art of Assembly Language" ...

    To nie jest książka dla początkujących. Poza tym jest w niej wiele błędnych kodów. Walczyłem z tym trochę. Dziwne, bo autor znany i uznany. Dla początkujących mogę polecić książkę "Asembler, ależ to bardzo proste" Jeefa Dutenmanna. Są też kursy w sieci choćby udzielającego się w tym wątku usera Dżyszla, którego pozdrawiam.
  • Użytkownik usunął konto  
  • Poziom 33  
    [quote="antekone"]
    Remeknapr napisał:
    Nie mierz proszę wszystkich swoją miarą. Ja się z niej uczyłem jako początkujący, dlatego polecam innym początkującym. Byłoby również miło, gdybyś podał przykład błędnego kodu.

    Kogo mierzę swoją miarą? Oceniam książkę, a nie człowieka. Chyba, że mówimy o różnych książkach. Jeśli chodzi o kod. Przerabiałeś rozdziały o operacjach arytmetycznych wielokrotnej precyzji? Np. dzielenie z użyciem dzielnika większego od rejestru procesora z użyciem przesunięć i obrotów?