ROZDZIAŁ CZWARTY ROZMIESZCZENIE W PAMIĘCI I DOSTĘP, INFORMATYKA, „THE ART OF ASSEMBLY LANGUAGE” [PL]

[ Pobierz całość w formacie PDF ]
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
WYŁĄCZNOŚĆ DO PUBLIKOWANIA TEGO TŁUMACZENIA
POSIADA
RAG
„THE ART OF ASSEMBLY LANGUAGE”
tłumaczone by KREMIK
Konsultacje naukowe: NEKRO
wankenob@priv5.onet.pl
nekro@pf.pl
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
ROZDZIAŁ CZWARTY:
ROZMIESZCZENIE W PAMIĘCI I DOSTĘP
Rozdział Pierwszy omawia podstawowe formaty danych w pamięci. Rozdział Trzeci pokazuje jak
system komputerowy fizycznie organizuje te dane. Ten rozdział omawia jak CPU 80x86 uzyskują dostęp do
danych w pamięci.
4.0 WSTĘP
Ten rozdział tworzy ważny pomost pomiędzy sekcją jeden i dwa (odpowiednio Organizacja
Maszynowa i Podstawy Języka Asemblera).Z punktu widzenia organizacji maszynowej, ten rozdział omawia
adresowanie pamięci, organizację pamięci ,tryby adresowania CPU i przedstawianie danych w pamięci .Z
punktu widzenia programowania w jeżyku asemblera, rozdział ten omawia zbiór rejestrów 80x86,tryby
adresowania pamięci 80x86 i złożone typy danych. Jest to rozdział kluczowy. Jeśli nie zrozumiemy materiału w
tym rozdziale, będziemy mieli kłopoty ze zrozumieniem następnych rozdziałów. Dlatego też, przestudiujmy ten
rozdział starannie zanim będziemy kontynuować.
Rozdział zaczyna się od omówienia rejestrów procesorów 80x86.Te procesory są wyposażone w zbiór
rejestrów ogólnego przeznaczenia, rejestry segmentowe i kilku rejestrów specjalnego przeznaczenia .Pewni
członkowie rodziny ,są wyposażeni w dodatkowe rejestry, chociaż typowe aplikacje ich nie używają.
Po przedstawieniu rejestrów ,rozdział opisuje organizację pamięci i segmentację w 80x86.Segmentacja
jest trudną koncepcją dla wielu początkujących programistów asemblerowych. Istotnie, tekst ten stara się unikać
adresowania segmentowego przez cały wstępny rozdział. Niemniej jednak. segmentacja jest potężną koncepcją
która musi stać się dobrze znana komuś kto chce pisać nie trywialne programy pod 80x86.
Tryby adresowania pamięci 80x86 są, być może ,najważniejszym tematem w tym rozdziale .Jeżeli nie
opanujesz całkowicie używania tych trybów adresowania ,nie będziesz mógł pisać rozsądnych programów
asemblerowych .Nie przechodź dalej nim zadowalająco nie zapoznasz się z trybami adresowania. Ten rozdział
omawia również rozszerzone tryby adresowania z procesora 80386 (i późniejszych). Wiedza o tych trybach
adresowania nie jest tak ważna ,ale jeśli się ich nauczymy, możemy używać ich kiedy piszemy kod dla
procesorów 80386 i późniejszych.
Rozdział ten również wprowadza garść instrukcji 80x86.Chociaż pięć lub więcej instrukcji tego
rozdziału jest niewystarczających dla napisania prawdziwego programu asemblerowego ,dostarczają one
wystarczającego zbioru instrukcji, który pozwala manipulować strukturą zmiennych i danych – temat
następnego rozdziału.
4.1 CPU 80x86: SPOJRZENIE PROGRAMISTY
Teraz ,jest czas aby omówić kilka prawdziwych procesorów:8088/8086/80188,80286 i
80386/80486/80586/Pentium.Rozdział Trzeci zajmował się dużo sprzętowymi aspektami systemu
komputerowego. Te komponenty sprzętowe wpływają na sposób w jaki piszemy programy ,lecz dla CPU jest
dużo więcej rzeczy niż tylko cykle magistrali i potoki. Jest czas spojrzeć na te komponenty CPU które są
bardziej widoczne dla nas, programistów asemblerowych.
Najbardziej widocznymi komponentami CPU jest zbiór rejestrów .Podobnie jak nasze hipotetyczne
procesory ,chipy 80x86 mają zbiór rejestrów zintegrowanych na płycie .Zbiór rejestrów dla każdego procesora w
rodzinie 80x86 jest nadzbiorem tamtych poprzednich CPU. Najlepszym miejsce do rozpoczęcia jest zbiór
rejestrów procesorów 8088,8086,80188 i 80186 ponieważ te cztery procesory mają takie same rejestry. Przy ich
omawianiu ,termin „8086” będzie sugerował każdy z tych czterech CPU.
Projektanci Intela
zaklasyfikowali rejestry 8086 do trzech kategorii: rejestry ogólnego przeznaczenia,
rejestry segmentowe i różnorodne rejestry .Rejestry ogólnego przeznaczenia są tymi które mogą stać się
operandami arytmetycznych ,logicznych i pokrewnych instrukcji. Chociaż te rejestry są „ogólnego
przeznaczenia”, każdy z nich ma swojej własne przeznaczenie. Intel używa terminu „ogólnego przeznaczenia”
luźno.8086 używa rejestrów segmentowych przy dostępie do bloków pamięci nazywanych, dość
niespodziewanie, segmentami. Zobacz „Segmenty w 80x86” po większą ilość szczegółów dotyczącą natury
rejestrów segmentowych. Ostatnią klasą rejestrów 8086 są
rejestry. Są dwa specjalne rejestry w tej grupie
które omówimy wkrótce.
4.1.1 REJESTRY OGÓLNEGO PRZEZNACZENIA 8086
Jest osiem 16 bitowych rejestrów ogólnego przeznaczenia w 8086: ax,bx,cx,dx,si,di,bp i sp .Możemy
używać wielu z tych rejestrów zamiennie w obliczeniach, wiele instrukcji pracuje bardziej wydajnie lub
całkowicie wymaga specyficznego rejestru z tej grupy. Tyle o ogólnym przeznaczeniu.
Rejestr
ax
(akumulator) występuje wszędzie tam gdzie mają miejsce arytmetyczne lub logiczne
obliczenia. Chociaż możemy wykonywać operacje arytmetyczne i logiczne na innych rejestrach ,często bardziej
wydajne jest używanie rejestru ax do takich obliczeń. Rejestr
bx
(bazowy) ma również kilka specjalnych
przeznaczeń .Jest on powszechnie używany do przechowywani adresu pośredniego, podobnie jak rejestr bx z
procesorów x86.Rejestr
cx
(licznik),jak wskazuje jego nazwa wskazuje służy do obliczeń
.
Często będziemy go
używać do zliczania iteracji w pętli lub specyfikowania liczby znaków w łańcuchu. Rejestr
dx
(danych) ma dwa
specjalne przeznaczenia: przechowuje przepełnienie z pewnych arytmetycznych operacji i przechowuje adresy
I/O kiedy uzyskujemy dostęp do danych na szynie I/O w procesorze 80x86.
Rejestry
si
i
di
(indeks źródłowy i indeks przeznaczenia) również mają kilka specjalnych przeznaczeń.
Możemy używać tych rejestrów jako wskaźników (podobnie jak rejestr bx) do pośredniego dostępu do pamięci
.Będziemy również używać tych rejestrów z instrukcjami łańcuchowymi 8086 kiedy przetwarzamy łańcuchy
znaków.
Rejestr
bp
(wskaźnik bazowy) jest podobny do rejestru bx. Ogólnie rzecz biorąc, będziemy używać
tego rejestru przy uzyskaniu dostępu do parametrów i zmiennych lokalnych w procedurze.
Rejestr
sp
(wskaźnik stosu) ma bardzo specjalne znaczenie – utrzymuje stos programu. Normalnie, nie
będziemy używać tego rejestru dla obliczeń arytmetycznych. Właściwe operacje większości programów zależą
od ostrożnego używania tego rejestru.
Poza tymi ośmioma 16 bitowymi rejestrami ,CPU 8086 ma również 8 ośmiobitowych rejestrów .Intel
nazywa te rejestry al.,ah,bl,bh,cl,ch,dl i dh. Prawdopodobnie zauważyłeś podobieństwa miedzy tymi nazwami a
nazwami kilku rejestrów 16 bitowych (ax,bx,cx i dx)Te ośmiobitowe rejestry nie są niezależnymi rejestrami al
reprezentuje „mniej znaczący bajt ax”,ah reprezentuje „bardziej znaczący bajt ax”. Nazwy innych
ośmiobitowych rejestrów znaczą to samo dla rejestrów bx,cx i dx. Rysunek 4.1 pokazuje zbiór rejestrów
ogólnego przeznaczenia.
Zauważ, że ośmiobitowe rejestry nie tworzą niezależnego zbioru rejestrów. modyfikowanie al. zmieni
wartość ax; więc zmodyfikuje ah .Wartość al. dokładnie odpowiada bitom od zera do siedem ax .Wartość ah
odpowiada bitom od osiem do piętnaście ax .Dlatego też modyfikacja al lub ah zmodyfikuje wartość ax
.Podobnie, zmodyfikowanie ax zmieni oba al. i ah .Zauważ, jednak ,że zmieniający się al. nie wpłynie na
wartość ah i vice versa .Odnosi się to również do bx/bl/bh,cx.cl.ch i dx,dl,dh.
Rejestry si,di,bp i sp są tylko rejestrami 16 bitowymi .Nie ma sposobu na bezpośredni dostęp do
pojedynczych bajtów w tych rejestrach tak jak możemy uzyskać dostęp do młodszych i starszych bajtów
rejestrów ax,bx,cx i dx.
Rysunek 4.1 Zbiór rejestrów 8086
4.1.2 REJESTRY SEGMENTOWE 8086
8086 ma cztery specjalne rejestry segmentowe:
cs
,
ds
,
es
i
ss
.Oznaczają one odpowiednio Segment
Kodu, Segment Danych, Segment Extra i Segment Stosu. Te rejestry wszystkie są szerokie na 16 bitów
.Zajmują się one wyselekcjonowywaniem bloków (segmentów) pamięci głównej. Rejestr segmentowy (np. cs)
wskazuje początek segmentu w pamięci.
Segmenty pamięci w 8086 nie mogą być dłuższe niż 65,536 bajtów .Jest to niesławne „ograniczenie
segmentu do 64K” przeszkadzające wielu programistom. Zobaczymy później kilka problemów z
ograniczeniem 64K,i kilka rozwiązań tego problemu.
Rejestr cs wskazuje segment zawierający obecnie wykonywane instrukcje maszynowe. Zauważmy ,że
pomimo ograniczenia segmentu do 64K,programy 8086 mogą być dłuższe niż 64K.Po prostu potrzebujemy
większą ilość segmentów kodu w pamięci. Ponieważ możemy zmieniać wartość rejestru cs ,możemy przejść do
nowego segmentu kodu kiedy chcemy wykonać kod tam umieszczony.
Rejestr segmentu danych, ds., ogólnie rzecz biorąc, wskazuje na globalne zmienne programu .Znowu
jesteśmy ograniczeni 65,536 bajtami danych w segmencie danych; ale zawsze możemy zmienić wartość rejestru
ds. aby uzyskać dostęp do dodatkowych danych w innym segmencie.
Rejestr ekstra segmentu, es ,jest dokładnie tym - rejestrem ekstra segmentu. Programy 8086 często
używają tego rejestru segmentowego aby uzyskać dostęp do segmentów kiedy trudno jest lub jest niemożliwe
modyfikowanie innych rejestrów segmentowych.
Rejestr ss wskazuje segment zawierający stos 8086.Stos występuje wtedy kiedy przechowujemy ważne
informacje stanu maszyny, powrót z podprogramu adresowania, parametry procedury i lokalne zmienne. Ogólnie
rzecz biorąc, nie modyfikujemy rejestru segmentu stosu ponieważ zbyt wiele rzeczy w systemie zależy od tego.
Chociaż jest teoretycznie możliwe przechowywać dane w rejestrach segmentowych, nie jest to dobry
pomysł. Rejestry segmentowe mają bardzo specjalne przeznaczenie – wskazywanie dostępnych bloków pamięci.
Próby używania tych rejestrów do innych celów mogą w wyniku dać wiele zmartwienia ,zwłaszcza jeśli
zamierzamy przejść na lepszy CPU np. 80386
Rysunek 4.2 : Rejestr Flag
4.1.3 REJESTRY SPECJALNEGO PRZEZNACZENIA 8086
Są dwa rejestry specjalnego przeznaczenia w CPU 8086: wskaźnik instrukcji (IP) i rejestr flag .Nie
uzyskamy dostępu do tych rejestrów w ten sam sposób jak do innych rejestrów 8086.Zamiast tego ,CPU
manipuluje tymi rejestrami bezpośrednio.
Rejestr IP jest odpowiednikiem rejestru IP procesorów x86 – zawiera adres obecnie wykonywanej
instrukcji .Jest to 16 bitowy rejestr ,który zapewnia wskaźnik do bieżącego segmentu kodu (16 bitów pozwala
wybrać jeden z 65,536 różnych komórek pamięci).Wrócimy do tego rejestru kiedy będziemy omawiać później
transmisję sterowania instrukcjami.
Rejestr flag nie jest podobny do innych rejestrów na 8086.Inne rejestry przechowują ośmio- lub 16
bitowe wartości. Rejestr flag jest po prostu zbiorem kompilacyjnych jednobitowych wartości które pomagają
określić bieżący stan procesora .Chociaż rejestr flag jest szeroki na 16 bitów,8086 używa tylko dziewięciu z tych
bitów. Z tych flag ,czterech flag używamy cały czas: znacznik zera, znacznik przeniesienia, znacznik znaku i
znacznik nadmiaru. Te flagi są kodami stanu 8086.Rejestr flag jest pokazany na rysunku 4.2
4.1.4 REJESTRY 80286
Mikroprocesor 80286 dodaje jedną ważną z programistycznego punktu widzenia cechę do 80286-
operacje trybu chronionego. Ten tekst nie obejmuje operacji trybu chronionego dla 80286 z różnych przyczyn.
Po pierwsze ,tryb chroniony 80286 był kiepsko zaprojektowany. Po drugie jest on interesujący tylko dla
programistów piszących swoje własne systemy operacyjne lub nisko poziomowe programy systemowe dla
takiego systemu operacyjnego .Nawet jeśli piszemy oprogramowanie dla trybu chronionego systemu
operacyjnego takiego jak UNIX czy OS/2 nie będziemy używać cech trybu chronionego 80286.Pomimo to jest
wart zachodu do wskazywania ekstra rejestrów i stanu flag obecnych w 80286 właśnie w przypadku natknięcia
się na nie.
Są trzy dodatkowe bity obecne w rejestrze flag 80286.Poziom Uprzywilejowania I/O to wartość dwóch
bitów (bity 12 i 13).Specyfikują jeden z czterech uprzywilejowanych poziomów potrzebnych do wykonania
operacji I/O. Te dwa bity generalnie zawierają 00b kiedy użytkujemy tryb rzeczywisty na 80286 (tryb
emulowany na 8086).Flaga NT (nested task – znacznik zagnieżdżonego zadania) steruje operacją instrukcji
powrotu z przerwania (IRET).Normalnie NT ma zero dla programu w trybie rzeczywistym.
Poza tymi ekstra bitami w rejestrze flag,80286 ma również pięć dodatkowych rejestrów używanych
przez system operacyjny do wspomagania zarządzania pamięcią i przetwarzanie wieloprogramowe :rejestr stanu
(msw),rejestr globalnej tablicy deskryptorów (gdtr)rejestr lokalnej tablicy deskryptorów(ldtr),rejestr tablicy
deskryptorów przerwań(idtr) i rejestr stanu zadania (tr)
Przy używaniu typowej aplikacji dla trybu chronionego na 80286,mamy dostęp do więcej niż jednego
megabajtu RAMu .jednakże 80286 jest praktycznie przestarzały a jest lepszy sposób dostępu do większej ilości
pamięci na późniejszych procesorach, programiści rzadko używają tej formy trybu chronionego.
4.1.5 REJESTRY 80386/80486
Procesor 80386 radykalnie rozszerzył zbiór instrukcji 8086.Dodatkowo wszystkie rejestry w 80286
(zatem i 8086),80386 dodał kilka nowych rejestrów i rozszerzył definicję istniejących rejestrów.80486 nie dodał
żadnych nowych rejestrów do podstawowego zbioru rejestrów 80386,ale zdefiniował kilka bitów w kilku
rejestrach niezdefiniowanych przez 80386.
Bardzo ważną zmiana, z punktu widzenia programisty, było wprowadzenie w 80386 zbioru 32
bitowych rejestrów .Ax,bx,cx,dx,si,di,bp,sp, flagi i rejestr ip ,zostały wszystkie rozszerzone do 32 bitów.80386
nazwał te 32 bitowe wersje eax,ebx,ecx,ex,esi,edi,ebp,esp, eflagi i eip w odróżnieniu ich od ich 16 bitowych
wersji (które są jeszcze dostępne w 80386) .Poza 32 bitowymi rejestrami,80386 również wprowadził dwa nowe
16 bitowe rejestry segmentowe fs i gs, które pozwalają programiście jednocześnie uzyskać dostęp do sześciu
różnych segmentów w pamięci bez ładowania rejestru segmentu. Zauważ ,że wszystkie rejestry segmentowe w
80386 są 16 bitowe.80386 nie rozszerzyły rejestru segmentów do 32 bitów ,jak zrobiły to z innymi rejestrami.
80386 nie zrobił żadnych zmian w bitach w rejestrze flag. Zamiast tego rozszerzył rejestr flag do 32
bitów (rejestr eflag) i zdefiniował bity 16 i 17.Bit 16 jest znacznikiem wznowienia(RF) i używanym w zbiorze
rejestrów uruchomieniowych .Bit 17 jest znacznikiem trybu V86(VM).który określa czy procesor pracuje w
trybie wirtualnym V86 (symulowanym w 8086) lub standardowym trybie chronionym.80486 dodaje trzeci bit do
rejestru eflag na pozycji 18 - flaga stanu wyrównania .Razem z rejestrem sterującym zero (CR0) w 80486,flaga
ta wymusza pułapkę (przerwanie programu) kiedy procesor uzyskuje dostęp do nie wyrównanych
danych.(np.
słowo spod nieparzystego adresu lub podwójne słowo spod adresu który nie dzieli się przez cztery)
80386 dodał cztery rejestry sterujące:CR0-CR3.rejestry te rozszerzają rejestr msw 80286 (80386
emuluje rejestr msw z 80286 dla kompatybilności ,ale informacja w rzeczywistości pojawia się w rejestrach
CRx)W 80386 i 80486 te rejestry sterują funkcjami takimi jak zarządzanie pamięcią stronicowaną
,włączanie/wyłączanie operacji pamięci podręcznej (tylko 80486),operacji trybu chronionego i innych.
80386/486 dodają również osiem rejestrów uruchomieniowych .Program uruchomieniowy taki jak
Microsoft Codeview lub Turbo Debugger mogą używać tych rejestrów do ustawiania punktów kontrolnych
,kiedy próbujemy zlokalizować błąd wewnątrz programu. Kiedy nie będziemy używać tych rejestrów w
programach użytkowych ,często odkryjemy ,że używanie takiego debuggera zredukuje czas potrzebny do
wyeliminowania błędów z naszych programów. Oczywiście, debugger który uzyska dostęp do tych rejestrów
będzie funkcjonował właściwie na procesorach 80386 lub późniejszych.
Ostatecznie, procesory 80386/486 dodają zbiór rejestrów testujących system ,które testują stosowne
operacje procesora kiedy system jest włączany. Jest prawdopodobne, że Intel dołoży te rejestry do chipu co
pozwoli testować bezpośrednio po produkcji ,ale projektanci systemu mogą wykorzystać te rejestry do robienia
testów po włączeniu zasilania.
Przeważnie programiści asemblerowi nie muszą martwić się ekstra rejestrami dodanymi do
procesorów 80386/80486/Pentium.Jednakże 32 bitowe rozszerzenie i ekstra rejestry segmentowe są całkiem
użyteczne. Dla programów użytkowych ,model programowania dla 80386/80486/Pentium wygląda jak ten
pokazany na rysunku 4.3
Rysunek 4.3 Rejestry 80386 (Dostępne programiście asemblerowemu)
4.2 FIZYCZNA ORGANIZACJA PAMIĘCI 80x86
Rozdział Trzeci omawiał podstawową organizację Architektury Von Neumanna (VNA) systemów
komputerowych. W typowej maszynie VNA,CPU łączy pamięć przez magistrale.80x86 wybiera kilka
szczególnych elementów pamięci używając liczb binarnych na magistrali adresowej. Innym sposobem
obejrzenia pamięci jest tablica bajtów .Pascalowska struktura danych, która z grubsza pokrywa się z pamięcią
będzie wyglądać tak:
Memory : array [0..MaxRAM] of byte;
Wartość na magistrali adresowej odpowiada indeksowi dostarczonemu do tablicy. Np. zapisaniu danych do
pamięci odpowiada :
Memory [adres] :=Wartość_Do_Zapisania;
Odczytaniu danych z pamięci odpowiada :
Wartość_Odczytana := Memory [adres];
Różne CPU mają różne magistrale adresowe które sterują maksymalną liczbą elementów w tablicy pamięci
(zobacz „Magistrala Adresowa”).Jednakże, bez względu na liczbę linii adresowych na magistrali ,większość
komputerów nie ma jednego bajtu pamięci dla każdej adresowalnej lokacji .Na przykład, procesor 80386ma 32
linie adresowe pozwalające zwiększyć pamięć do czterech gigabajtów. Bardzo mało systemów 80386 w
rzeczywistości ma cztery gigabajty .Zazwyczaj, mamy od jednego do 256 megabajtów w systemach opartych 0
80x86.
Pierwszy megabajt pamięci ,od adresu zero do 0FFFFFh jest specjalny w 80x86.Odpowiada to całej
przestrzeni adresowej mikroprocesorów 8088,8086,80186 i 80188.Większość programów DOS ogranicza swoje
programy i adresy danych do lokacji w tym zakresie. Adresy ograniczone do tego zakresu są nazywane
adresami rzeczywistymi po trybie rzeczywistym 80x86.
4.3
SEGMENTY W 80x86
Nie możemy omawiać adresowania pamięci w rodzinie procesorów 80x86 bez omówienia najpierw
segmentacji. Pomiędzy innymi rzeczami, segmentacja dostarcza silnych mechanizmów zarządzania
pamięcią. Pozwala to programistom dzielić swoje programy na moduły które działają niezależnie jeden od
drugiego. Segmenty dostarczają sposobu łatwej implementacji programów zorientowanych obiektowo.
Segmenty pozwalają dwóm procesom łatwo dzielić dane. W sumie, segmentacja jest rzeczywiście zgrabną
cechą. Z drugiej strony, jeśli spytamy programistów co myślą o segmentacji, co najmniej dziewięciu na
dziesięciu stwierdzi ,że to straszne. Dlaczego taka odpowiedź?
Cóż, okazuje się,że segmentacja dostarcza drugiej zmyślnej cechy: pozwala nam rozszerzyć
adresowalność procesora. W przypadku 80x86,segmentacja pozwoliła projektantom Intela rozszerzyć
[ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • tejsza.htw.pl
  •