POLITECHNIKA ŁÓDZKA
Wydział Elektrotechniki i Elektroniki
Procesory INTEL 80X86
ŁÓDZ 2002
1. Mikroprocesor ... ?
Mikroprocesor (µP), jest to arytmetyczno-logiczna jednostka centralna (procesor) komputera, zminiaturyzowana do tego stopnia, że mieści się w układzie scalonym LSI (lub w kilku układach). Termin mikroprocesor został użyty po raz pierwszy w 1972 r., jednakże "era" mikroprocesorów rozpoczęła się w 1971 r. wraz z wprowadzeniem przez firmę Intel układu 4004 mikro-programowalnego komputera jedno-układowego. W układzie tym umieszczono: 4-bitowy sumator, 16 cztero-bitowych rejestrów, akumulator i stos, czyli podstawowe podzespoły jednostki centralnej systemu komputerowego. Układ 4004, składający się z 2300 tranzystorów, mógł wykonywać 45 różnych instrukcji, przy czym architektura jego była zbliżona do układów kalkulatorowych. Kolejne generacje mikroprocesorów 8, 16 i 32-bitowych, powstały odpowiednio w latach 1972, 1974 i 1981. W tym okresie liczba tranzystorów w układzie mikroprocesorowym zwiększyła się 200 razy, a szybkość przetwarzania 50 razy. Podobnie jak procesor w komputerze, mikroprocesor nie jest jednostką zdolną do samodzielnej pracy, lecz wymaga połączenia z innymi układami systemu mikroprocesorowego, takimi jak pamięci oraz układy i urządzenia wejścia/wyjścia. Poszczególne bloki systemu mikroprocesorowego są połączone szynami: adresową, danych i sterującą. Mikroprocesor realizuje operacje arytmetyczno-logiczne i koordynuje pracę całego systemu. Pamięć przechowuje program w postaci ciągu instrukcji oraz dane niezbędne do realizacji wykonywanego programu i wyniki końcowe. Układy We/Wy pośredniczą w przekazywaniu informacji między procesorem, pamięcią a urządzeniami zewnętrznymi lub innymi obiektami będącymi źródłem lub odbiorcą informacji przetwarzanych w systemie. Urządzenia zewnętrzne są końcówkami systemu mikroprocesorowego, za pośrednictwem, których odbywa się przetwarzanie informacji umieszczonej na różnych nośnikach (taśma magnetyczna, dyskietki, taśma dziurkowana itp.) w postać wymaganą przez pozostałe układy systemu mikroprocesorowego. Człowiek kontaktuje się z systemem mikroprocesorowym za pośrednictwem, odpowiednich urządzeń zewnętrznych, tj. klawiatury, wskaźników, drukarki, monitora i ewentualnie syntezatora i analizatora mowy. W miarę rozwoju technologii wytwarzania układów scalonych LSI przejawia się tendencja do scalania funkcji, tj. wytwarzania w jednym układzie scalonym mikroprocesora wraz z innymi układami systemu, µP. Jeżeli taki układ zawiera wszystkie podstawowe bloki funkcjonalne, stanowiące kompletną strukturę komputera, to nazywamy go mikrokomputerem jedno-układowym.
1.1 Budowa mikroprocesora .
Typowy ၭP składa się z:
Licznik programu (programm counter - pc) - rejestr ten służy do adresacji pamięci programu. Po pobraniu kolejnej instrukcji jest on inkrementowany (nie dotyczy: skoków, powrotów, przerwań). Ilość bitów pc jest tożsama z szerokością linii adresowej.
Układ arytmetyczno - logiczny (aritmetic logic unit - ALU) - z układem tym jest związany rejestr bitów warunkowych, które ustawiane są wskutek działania operacji arytmetycznych i logicznych, bity te decydują o wykorzystaniu instrukcji (warunkowych, skoków, a także wywołań i powrotów)
Wskaźnik stosu (stack poiner - sp) - rejestr ten adresuje wydzielony obszar pamięci danych (RAM), w których ulokowany jest stos. Służy on do przechowywania adresów powrotnych przy stosowania techniki podprogramu i przy przerwaniach. W zwykły sposób dostęp do stosu może nastąpić tylko do jego wierzchołka (przy zapisie na stos sp jest dekrementowany, a przy odczycie sp zwiększa się - redekrement, postinkrement). Oprócz pamiętania - celem późniejszego odtworzenia adresów powrotnych - stos wykorzystuje się także do zachowania stanów innych rejestrów a nie tylko pc, może także być wykorzystywany jako chwilowa pamięć, można się nim posiłkować, przekazując dane z programu głównego do procedury i z powrotem.
Rejestry znajdujące się w ၭP mają różne funkcje: rejestry danych, adresowe, indeksowe, uniwersalne czy tzw. akumulatory czyli rejestry będące argumentem większości operacji arytmetycznych i logicznych. W miarę rozwoju ၭP następował wzrost liczby rejestrów ponieważ przyspiesza to wykonywanie programu. Użyte rejestry mogą być dedykowane (przypisane są im na stałe pewne funkcje), mogą także występować zestawy rejestrów tzw. symetrycznych (każdy może zastąpić inny)
Układy zegarowe, sterowania, magistrale wewnętrzne, bufory magistral, itp.
1.2 Technologia.
Początkowo mikroprocesory były wytwarzane przy użyciu technologii PMOS. W 1974 r. firma RCA wyprodukowała układ 1802, pierwszy mikroprocesor w technologii CMOS. Poszczególne firmy wytwarzają mikroprocesory technologiami najbardziej przez nie opanowanymi, dlatego w różnych typach układów mikroprocesorowych spotyka się prawie wszystkie technologie półprzewodnikowe. I tak firma Intel zastosowała w mikroprocesorze 8080 technologię MOS z tranzystorami z kanałem wzbogacanym typu n, a w układzie 8085 - technologię MOS z tranzystorami z kanałem typu n wzbogacanym i zubożanym. Firma Fairchild w układzie 9440 użyła technologii bipolarnej TTLS, a w mikroprocesorze 16-bitowym - technologii I2L. Wraz ze wzrostem liczby tranzystorów w mikroprocesorze większość wytwórców zaczęta stosować technologię MOS zamiast bipolarnej, przy czym najczęściej stosuje się technologię NMOS, dzięki której uzyskuje się dużą gęstość upakowania i dużą szybkość przełączania. Zastosowanie w technologii NMOS tranzystorów o małych rozmiarach (technologia HMOS) umożliwiło zwiększenie gęstości upakowania. Przykładem rozwoju technologii NMOS są dwa mikroprocesory firmy Intel: układ 8086 wytworzony w 1978 r. zawiera 29 000 tranzystorów w strukturze o powierzchni 31 mm2, a układ 80286 wytworzony w 1982 r. zawiera 130 000 tranzystorów w strukturze o powierzchni 45 mm2. Coraz większą popularność zdobywa w produkcji mikroprocesorów technologia CMOS, dzięki której uzyskuje się przyrządy o dużej szybkości przetaczania, dużej odporności na zakłócenia i małym poborze mocy,
Procesory INTEL 80x86.
Układ 8086 wywodzący się strukturalnie jeszcze z pierwotnego 8080 dał początek całej rodzinie ၭP charakteryzujących się przenoszalnością kodu z ၭP starszych do nowszych. Układ podstawowy adresuje przestrzeń 220 z tym, że bezpośrednio dostępne są tylko cztery, 64-ro kilobajtowe segmenty (kodu, danych, stosu i dodatkowy), a wyjście poza segment wymaga każdorazowo przeładowania odnośnych rejestrów segmentowych. Układ 8088 jest identyczny funkcjonalnie tylko dysponuje nie 16-to lecz 8-mio bitową szyną danych
.Kolejny ၭP rodziny, 80186 (80188 - 8 bitowa szyna danych) zawarł w strukturze oprócz 8086 (większość instrukcji zoptymalizowana czasowo) także podzespoły sprzętowe systemu tj. kontroler przerwań, sterownik DMA, timery, czy logikę selekcji banków pamięci.
Od ၭP 80286 wprowadzono możliwość przejścia do tzw. trybu wirtualnego, w którym ၭP uzyskuje dostęp (pozorny) do znacznie większych zasobów pamięciowych niż wynika to z 24 bitowej szyny adresowej. Wprowadzono także 4 poziomy uprzywilejowania (0 - nadzorca, ... , 3 - użytkownik). Przed przełączeniem w tryb wirtualny (software'owo) każdy ၭP (od 80286) zachowuje się tylko jak odpowiednio coraz szybszy układ pierwotny 8086.
W układzie 80286 zachowano 64 kbajtowy rozmiar segmentów. Ograniczenia na wielkość segmentów przestały być istotne dopiero od ၭP 80386, gdzie równają się one całemu obszarowi adresowemu 232 bajtów (wartość maksymalna), ၭP ten posiada również wewnętrzną 32 bitową architekturę, a model pracy w trybie wirtualnym z niewielkimi uzupełnieniami obowiązuje aż do najnowszej wersji Pentium®.
80386 musiał posiłkować się dedykowanym kontrolerem w przypadku dołączania szybkich pamięci podręcznych. Równolegle z układami rodziny konstruowano koprocesory numeryczne: 8087, 80287, 80387.
Te dwa ostatnie mogły również pełnoprawnie pracować z 80386. Poprzez integrację koprocesora, sterownika pamięci podręcznej, pamięci podręcznej i CPU 80386 powstał ၭP 80486.
Kolejne jego wersje rozwojowe idą głównie w kierunku zwiększenia szybkości przetwarzania i dodaniu różnych funkcji pomocniczych, w niczym nie zmieniając jego modelu programowego dla użytkownika i zasady pracy trybu wirtualnego.
W związku z przenoszalnością kodu i tym, że układ podstawowy 8086 dysponuje rozkazami jedno-, dwu-, trzy-, cztero-bajtowymi w rodzinie Intela nie występuje wyrównanie binarne w przypadku dostępu do kodu. Wyrównanie takie wprowadzono na zasadzie dobrowolności tylko w przypadku dostępu do danych począwszy od 80486.
.
Mikroprocesor 8086.
Mikroprocesor 8086 jest podstawową konstrukcją komputerów IBM PC/XT (ang. extended technology). Jest to jeden z pierwszych, szerzej rozpowszechnionych procesorów 16-bitowych, który posiada 16-bitową szynę danych.
Ważniejsze dane to:
1 MB przestrzeni adresowej pamięci (20 linii),
64 KB przestrzeń adresowa we/wy,
podział na dwa niezależne układy umożliwiające równoległe wykonywanie bieżącego rozkazu i pobieranie rozkazów następnych,
dwa tryby pracy - minimalny i maksymalny,
jedno napięcie zasilania,
częstotliwość zegara: 4, 5, 8, 10 MHz
Strukturę wewnętrzną można podzielić na dwie jednostki: układ sterowania magistrali BIU (Bus Interface Unit) i układ wykonawczy (Execution Unit).
ၭP ten dysponuje multipleksowaną szyną adres-dane. W zależności od sygnału na nóżkę MN/MX pracuje w trybie maksymalnym lub minimalnym (tryb minimalny wprowadzono, aby zapewnić kompatybilność z interfejsami 8085, stosowany zwykle w systemach jednoprocesorowych). Jedynie tryb maksymalny umożliwia pełne wykorzystanie ၭP i bezpośrednią współpracą z koprocesorem 8087. Tryb maksymalny oprócz zegara 8284 wymaga dołączenie sterownika magistrali 8288, który na podstawie statusu zegarowego ???
,
,
oraz wspólnego z ၭP sygnału zegarowego wytwarza komplet sygnałów sterujących magistralą (odpowiednie sygnały
,
,
,
,
) oraz sygnały sterujące zatrzaskami „zdejmującymi” adres z multipleksowanej linii i dwukierunkowymi wzmacniaczami szyny danych. Wyższe linie statusowe są multipleksowane z A16 do A19. Informują one o używanym w cyklu rejestrze segmentowym
,
i o stanie zezwolenia na przerwanie (
),
,
- niewykorzystywany. Jak każdy 16-bitowy ၭP 8086 posiada kolejkę instrukcji do wykonania - 6 bajtowa (4 bajtowa dla 8088). Stan zapełnienia kolejki (istotny przy współpracy z koprocesorem) jest wyprowadzony na linię
,
. W 8086 wprowadzono nietypowy sposób przejmowania magistrali (dotyczy trybu maksymalnego). Są to dwukierunkowe linie
,
,
.
Na każdej z tych linii (zerowa - 1 priorytet) obowiązuje 3-impulsowa sekwencja żądania, potwierdzenia, zwolnienia. Każdy z tych impulsów musi być dłuższy od okresu zegara (aktywny poziom niski).
Linia LOCK w przypadku swojej aktywności oznacza, że ၭP nie odda magistrali po skończeniu bieżącego jej cyklu. Aktywność następuje w przypadku:
całego rozkazu, jeśli poprzedzony on był przedrostkiem LOCK (bajt #F0),
pomiędzy dwoma cyklami akceptacji przerwania.
Podwójna sekwencja cyklu akceptacji wynika z konieczności współpracy z kontrolerami przerwań 8259, które dopuszczają pracę kaskadową. W związku z tym w 1 cyklu akceptacji rozstrzygane są tylko priorytety pomiędzy nadrzędnym sterownikiem a podporządkowanymi.
Istnieje możliwość zewnętrznej synchronizacji programy poprzez wejście TEST. Rozkaz
powoduje zatrzymanie ၭP aż do momentu stwierdzenia aktywnego zbocza na wejściu TEST. Logika ta standardowo jest wykorzystywana do współpracy z koprocesorem, na to wejście podłączane jest wyjście BUSY informujące o zajętości jednostki zmiennoprzecinkowej.
8086 dysponuje 16-bitowym tzw. adresem logicznym i 20-bitowym adresem fizycznym. Przejście pomiędzy adresami wykorzystuje odpowiednie rejestry segmentowe. Adresem logicznym jest:
w przypadku pobierania kodu - zawartość IP,
przy dostępie do stosu - zawartość SP,
przy dostępie do danych wartość wynikająca z trybu adresacji.
W przypadku adresacji wykorzystywane są rejestry BX, BP, SI, DI oraz wartości bezpośrednie.
Adres fizyczny powstaje przez zsumowanie adresu logicznego z przesuniętą o 4 bity zawartością rejestru segmentowego.
Segmenty przestrzeni adresowej mogą być ułożone oddzielnie lub zachodzić na siebie całkowicie lub częściowo. Przykładowo jeżeli chcemy aby ၭP sam modyfikował swój kod musimy doprowadzić do odpowiedniego pokrycia się segmentu kodu i danych. Zamiast segmentu danych możemy używać alternatywnie segmentu dodatkowego skojarzonego z rejestrem ES (CS, DS., SS, ES - rejestry segmentowe).
Segmenty używane są domyślnie i istnieje możliwość wymuszania software'owego innego segmentu stosując przed rozkazem odpowiedni przedrostek. Należy pamiętać jednak, że nic nie osiągniemy w przypadku dostępu do kodu, stosu, oraz w przypadku dostępu do argumentu przeznaczenia w rozkazach blokowych (łańcuchowych).
Tryby adresacji stosujące jakiekolwiek konfiguracje rejestru bazy BP używają zamiast domyślnego segmentu DS, segment stosu SS (rejestr BP jest rezerwowym wskaźnikiem stosu).
Można zauważyć, że ten sam adres fizyczny powstaje przez zsumowanie różnych wartości segmentu i adresu logicznego (offset). Konsekwencją segmentacji jest też rozróżnienie w przypadku skoków, wywołań i powrotów wersji wewnątrzsegmentowej (bliskiej) i pozasegmentowej (dalekiej). W przypadku wersji wewnątrzsegmentowej zmianie ulega wyłącznie zawartość IP (stosowana jest w konsekwencji adresacja względna), zaś w przypadku wersji międzysegmentowej należy także zdefiniować nowy stan rejestru CS.
Po wyzerowaniu ၭP oprócz zablokowania przerwań INTR, zeruje zawartość IP, DS, SS, ES a jedynkuje zawartość CS. W konsekwencji adresem startowym (jest stan KO pierwszego rozkazu) będzie lokacja FFFF0.
Każdy ၭP rodziny zaczyna pracę od lokacji 16-tej przed końcem przestrzeni adresowej.
Powyższy rysunek przedstawia ułożenie segmentów po wyzerowaniu ၭP. Jeżeli w ostatnich 16 bajtach nie znajdzie się skok pozasegmentowy (zmieniający CS) to położenie segmentu nie ulegnie zmianie zaś po lokacji FFFFF ၭP rozpocznie odczyt kodu od lokacji 00000. Praktyką jest umieszczanie w ostatnich 16 bajtach dalekiego skoku ponieważ w pierwszym kbajcie przestrzeni adresowej znajdują się adresy startowe (w postaci CS, IP) ładowane do tych rejestrów w przypadku stanów wyjątkowych wewnętrznych przerwań.
W poniższej tabeli pierwsze 32 adresy są przeznaczone dla ၭP zaś pozostałe dla obsługi przerwań użytkownika. 8086 wykorzystuje jedynie 5 pierwszych adresów.
„0” : dzielenie przez zero
„1” : śledzenie, programowa praca krokowa
„2” : przerwanie niemaskowalne
„3” : pułapka programowa
„4” : rozkaz przerwania programu przy nadmiarze INT0
Obsługa każdego stanu wyjątkowego i przerwania kończy się rozkazem IRET, który odtwarza ze stosu poprzednie wartości CS, IP, F (flag - rejestr statusowy) - w sumie 6 bajtów (każdy rejestr 2 bajty), gdyż obsługa przerwania stanu wyjątkowego jest zawsze typu dalekiego tzn. przy wejściu w obsługę ၭP określa nową wartość CS oraz IP, a stare razem z oboma bajtami rejestru statusowego umieszcza na stosie. Istnieje możliwość software'owego wywołania każdej procedury (adresy startowe z pozycji 0÷255) przy pomocy rozkazu INTnr:
Wykonanie tej instrukcji nie jest oczywiście uwarunkowane stanem bitu zezwolenia na przerwanie, co więcej rozkaz ten (podobnie jak w przypadku przerwania zewnętrznego, czy wewnętrznego stanu wyjątkowego) zeruje bit I oraz bit T (programowej pracy krokowej).
Dla INT3 istnieje dualna 1 bajtowa postać rozkazu używana przy zakładaniu pułapek programowych.
Znaczna część KO zawiera w sobie pole REG, MOD i R/M. Pole REG określa używany rejestr (w zależności od bitu W - ośmio lub szesnastobitowy), natomiast pola MOD i R/M definiują położenie argumentu pamięci. Możliwe są różne warianty, których składnikami są rejestry BX, BP, SI, DI a także adresy (przesunięcie bezpośrednie - dla przypadku MOD=00 i R/M=110). Pola MOD i R/M mogą także definiować rejestr, gdy MOD=11. Jeżeli dany rozkaz korzysta z dwóch argumentów, to co najmniej jeden z nich musi znajdować się w pamięci. W przypadku pojedynczego argumentu nie występuje pole REG tylko para MOD i R/M. Tworząc adres argumentu korzystamy domyślnie z segmentu DS, chyba że przepis na jego adres zawiera rejestr BP (rezerwowy wskaźnik stosu), gdyż wtedy stosuje się segment SS. Wymuszenie innego segmentu jest możliwe za pomocą przedrostka. Segmentacja powoduje, że skoki, wywołania i powroty występują w dwóch wersjach. Dla skoków i wywołań wersji pośredniej pola MOD i R/M zawarte w drugim bajcie mogą określać:
Rejestr, gdzie znajduje się nowa wartość IP
Komórkę pamięci od której zapisane są nowe wartości IP, bądź IP a następnie CS
Obie wersje powrotu (bliska i daleka) posiadają „mutacje”, które ponadto umożliwiają dodanie bezpośrednio do SP przesunięcia (ma sens tylko dodatnie) po zakończeniu ściągania ze stosu IP, bądź IP wraz z CS. Mutacji tej używamy do usunięcia ze stosu parametrów pozostawionych tam przez podprogram. Wszystkie skoki warunkowe operują na przesunięciu ośmiobitowym, dotyczy to także pętli LOOP i jej wersji uwzględniającej jako warunek wyjścia nie tylko wyzerowanie CX lecz także stan Z=1, lub Z=0. Rozkaz JCXZ służy do „ręcznego” zamykania pętli przy innych warunkach.
Wykorzystanie rejestrów w rozkazach 8086 nie jest symetryczne, pewne rejestry są na stałe przypisane do pewnych rozkazów. Utrudnia to pisanie programów, a z drugiej strony daje pewną zwięzłość kodu (program jest krótszy).
W rozkazach transferu wyróżniono ładowanie bezpośrednie do rejestru lub pamięci, a w szczególności skróconą wersję do tych rejestrów. Oddzielne instrukcje odnoszą się do przesłań z udziałem rejestrów segmentowych (definiuje je dwubitowe pole REG). Jeżeli rozkaz zawiera i dane i przesunięcie bądź adres bezpośredni to za KO jako pierwszy umieszczony zostanie adres, a dopiero potem bajty danych. Bit W definiuje rozmiar argumentu; w zależności od jego stanu dwubitowe pole REG uzyskuje inne znaczenie.
Intel konsekwentnie stosuje notacje: najmłodszy bajt na początek. Domyślnym rejestrem segmentowym jest rejestr DS (bądź SS), chyba że użyjemy przedrostka. Jeśli ma to sens to Intel dopuszcza użycie większej ilości przedrostków, kolejność nie ma znaczenia (poza specjalnymi wyjątkami). Na stos można zapisać bądź zdjąć dowolny rejestr lub komórkę pamięci zdefiniowaną przez pola MOD i R/M. W rozkazie wymiany nie mogą brać udziału rejestry segmentowe; wymiana akumulatora z akumulatorem to rozkaz NOP. Jak w każdym Intelu istnieje wydzielona przestrzeń we/wy o objętości 64kB. Jest ona adresowana w sposób pełny, za pomocą DX, bądź jedynie na ośmiu najmłodszych liniach przy pomocy adresowania bezpośredniego (drugi bajt za KO). Nieużywane wyższe linie adresowe przy rozkazach we/wy μP ustawie na zero. Jeżeli przy rozkazie IN OUT bit W=0 ??? to następuje przesłanie całego akumulatora w dwóch cyklach zawsze po dolnej połówce DB. Młodszy bajt pod wskazany adres i starszy pod adres o jeden większy.
Dopiero w `386 operacje we/wy wykorzystują całą 32 bitową szynę danych do przesyłania słowa, bądź długiego słowa. W przypadku Pentium porty DB 32 do 63 nie są wtedy wykorzystywane. Przestrzeń we/wy nie podlega procesowi segmentacji.
15 |
|
07 |
|
00 |
|||
1 |
0 |
||||||
3 |
2 |
||||||
5 |
4 |
||||||
|
|
Instrukcja XLAT służy do przekodowania wartości zawartej w rejestrze AL wg tablicy adresowanej rejestrem BX.
(BX+AL):DS AL segmentacja względem DS
Jeżeli chcemy wyznaczony adres argumentu zachować w jednym z rejestrów to używamy instrukcji LEA(load effective adress). Ładuje ona przesunięcie wyznaczone względem pól MOD i R/M do rejestru wskazanego polem REG. Instrukcja ta jest pożyteczna przy tworzeniu procedur relokowalnych, dotyczy to także rozkazów LDS i LES.
Dwie powyższe instrukcje ładują do μP przechowywany w pamięci pełny adres argumentu z segmentu danych bądź dodatkowego. Rozkazy te jak i wszystkie inne zmieniające rejestry segmentowe wykonują się inaczej w trybie wirtualnym.
Bity warunkowe
W przypadku bitów warunkowych dedykowane instrukcje dotyczą tylko bitu carry, direction oraz bitu zezwalającego na przerwanie. Dolny bajt rejestru statusowego może wymieniać też z rejestrem AH. W przypadku konieczności zmiany stanu bitów (starszy bajt) musimy zastosować operacje:
1. flagi na stos
2. ze stosu na akumulator
3. ustawienie bądź wyzerowanie
4. akumulator na stos
5. ze stosu do rejestru F
Procedura taka dotyczy szczególnie zainicjowania programowej pracy krokowej poprzez ustawienie bitu T.
Rozkaz HALT zachowuje się identycznie jak w Z80, po jego stwierdzeniu μP wstrzymuje zapełnianie kolejki. Kolejka natomiast jest ładowana w przypadku instrukcji WAIT, po stwierdzeniu wyróżnionego zbocza na wyjściu TEST μP rozpoczyna wykonywanie uprzednio zgromadzonych instrukcji.
Rozkazy blokowe
Istnieją instrukcje, które poprzedzone przedrostkiem RET wykonują się w sposób blokowy. Dotyczy to przesłań i porównań. Ponadto możliwe jest przesyłanie w ten sposób danych pomiędzy pamięcią a układami we/wy (przestrzeń). 8086 nie cofa PC aby za każdym razem ponownie pobierać KO. Rozkazy blokowe są oczywiście przerywane po każdym nawrocie, a po każdym cyklu może być zabrana magistrala, chyba że rozkaz oprócz przedrostka REP poprzedzany jest przedrostkiem LOCK.
Licznik obiegu zawiera rejestr CX, a kierunek zmiany adresu określa bit D w rejestrze statusowym. Transfer i porównanie blokowe może być w formie bajtu lub słowa. Maksymalny blok transferowany wynosi 64 kB. Oprócz zwykłego przedrostka REP
występują także wersje warunkowe REPZ, REPNZ uzależniające dalsze powtarzanie od stanu bitu zerowości.
W --> [Author:RD] przypadku, gdy w instrukcji pole MOD=01 to za KO znajduje się jednobajtowe przesunięcie, jeżeli MOD=10 jest to przesunięcie dwubajtowe, zaś jeśli MOD=00 i R/M=110 to za KO znajdują się 2 bajty adresu bezpośredniego. Ewentualne dane natychmiastowe są lokowane zaraz po bajtach związanych z adresem.
Na liście rozkazów 8086 i następnych występują rozkazy, które mogą być wykonywane wielokrotnie jeżeli zostaną poprzedzone przedrostkiem powtórzenia lub powtórzenia warunkowego (zależność wyłącznie od bitu Z).
Przed rozkazami SCAS, CMPS może wystąpić jedynie przedrostek powtarzania warunkowego. Np. w przypadku REPZ powtarzanie odbywa się do momentu wyzerowania rejestru długości bloku lub stwierdzenia zerowej wartości bitu Z. Czasem używa się oznaczeń REPZ (REPE). Rozkazy blokowe nie powodują wielokrotnego odczytywania kodu operacyjnego. Obowiązują identyczne reguły odnośnie przejęcia magistrali i akceptacji przerwania jak dla rozkazów blokowych w Z80. Odnośnie przejmowania magistrali od 8088 obowiązuje jeszcze reguła, że przesłanie 16 bitowe z 8086 wykonywane przez 8088 w dwóch ratach nie powodują oddania magistrali pomiędzy tymi cyklami. W rozkazach łańcuchowych mamy możliwość zmiany jedynie rejestru segmentowego źródła. W zależności od użytego rozkazu łańcuchowego można zastosować tylko wskazany powyżej przedrostek np. rozkaz MOVS nie może być poprzedzony przedrostkiem warunkowym (μP potraktuje to jak zwykłe RET, począwszy od 8086 ??? zgłosi wyjątek nr 6 - nielegalnej instrukcji).
8086 jest stosunkowo tolerancyjny na różnie nie zawsze celowe działanie programisty. Wyższe Intele zachowują się bardziej restrykcyjnie obejmując coraz większym zasięgiem powody zgłoszenia wyjątku nr 6. Przykładowo począwszy od `386 użycie przedrostka LOCK jest dopuszczone tylko dla takich instrukcji (z odpowiednim trybem adresacji), które powodują modyfikację argumentu pamięci (odczyt, modyfikacja, zapis).
Teoretycznie przed rozkazem łańcuchowym można użyć wszystkich 3 przedrostków (LOCK, SEG, REP) należy jednak pamiętać, że w przypadku akceptacji przerwania μP położą jako adres powrotu na stosie adres najbliższego przedrostka przed rozkazem.
Przykład:
W 1) po powrocie z przerwania μP odda magistralę, a w 2) magistrali nie odda, ale wykona już tylko 1 powtórzenie.
W przypadku przesunięć i powrotów w KO znajduje się bit V. Dla:
V=0 - operacja o 1 bit,
V=1 - ilość przesunięć określa rejestr CL.
μP sięga do tabeli z adresami startowymi obsług stanów wyjątkowych (wewnętrznych lub przerwań) w następujących przypadkach:
Przerwanie INTR (dwa cykle INTa)
Przerwanie NMI (cykle INTa nie występują, domyślnie pozycja druga w tabeli)
Stan wyjątkowy wewnętrzny (w przypadku 8086 jest to wyłącznie dzielenie przez zero).
Rozkaz INT nr (numer dowolny, dla numeru 3 jest także wersja jednobajtowa rozkazu).
W przypadku NMI dzielenia przez zero i rozkazu INT nr działanie μP nie zależy od stanu bitu I.
Realizacja śledzenia następuje (stan wyjątkowy po każdym rozkazie) jeśli bit T=1.
Wejście w obsługę jakiegokolwiek stanu wyjątkowego (wewnętrznego lub zewnętrznego) powoduje, że:
μP składa na stosie 6 bajtów (flagi, CS, IP),
We wnętrzu zeruje bity I oraz T,
Odczytuje z odpowiedniej pozycji w tabeli adres startowy.
Ze względu na działanie kolejki operacja c) wykona się przed a), dzięki temu w trakcie składania na stos może ruszyć wg nowych CS, IP układ kolejki.
Generalnie obowiązuje zasada, że obsługa śledzenia wykonuje się przed obsługą przerwania, nawet NMI. Intel 8086 pomiędzy dwiema instrukcjami może wstawić jedynie maksymalnie 2 obsługi (zapisuje na stosie jedynie dwie warstwy).
Jako przerwanie rozumiemy wejście INTR, NMI, rozkaz INTnr lub stan wyjątkowy wewnętrzny (dzielenie przez zero). W trzech ostatnich przypadkach nie występują cykle INTa.
W przypadku przerwania podczas śledzenia μP wykona następujące czynności:
Podwójny cykl INTa (tylko w przypadku przerwania INTR),
Odczyta z tabeli adres startowy obsługi przerwania,
Położy na stosie warstwę I (współbieżnie z zapisem stosu ruszy kolejka wprowadzając do μP bajty z początku programu obsługi przerwania),
Z tabeli adresów startowych μP odczyta warstwę CS, IP dla pozycji pierwszej (lokacje 4,5,6,7 - śledzenie),
Na stosie wyląduje warstwa II (współbieżnie μP rozpocznie pobieranie do kolejki pierwszych bajtów obsługi śledzenia),
Obsługa śledzenia (bit T=0, tzn. nie może śledzić sam siebie oraz I=0 - blokada przerwań), ???
Rozkaz IRET kończący śledzenie ściąga warstwę II,
Wykonywana jest obsługa przerwania (dalej I=T=0),
Rozkaz IRET kończy obsługę przerwania - ze stosu ściągana jest warstwa I i μP wraca do programu głównego.
Zauważamy, że podczas obsługi przerwania zostaje zawieszone śledzenie. W przypadku konieczności zachowania ciągłości śledzenia (np. cele uruchomieniowe) można oczywiście na początku każdej procedury obsługi przerwania wstawić sekwencję ustawiającą T=1, lecz bardziej eleganckim rozwiązaniem jest poprawienie w warstwie II na stosie na T=1, gdyż wtedy IRET kończący śledzenie spowoduje przejście do obsługi przerwania z podtrzymaniem śledzenia.
Zgodnie z podanymi uprzednio regułami:
Dla INTR, NMI i śledzenia wykona się obsługa śledzenia, NMI, obsługa INTR zaczeka na okazję po następnym rozkazie.
INTR, śledzenie oraz rozkaz INTnr (względnie dzielenie przez 0) - μP wykona śledzenie, a potem obsługę stanu wyjątkowego lub rozkazu, INTR zaczeka na następny rozkaz.
NMI, INTnr (lub stan wyjątkowy wewnętrzny) oraz śledzenie - w tym przypadku nie można zapewnić ciągłości śledzenia gdyż μP wykona najpierw obsługę NMI, a potem obsługę rozkazu INTnr lub stanu wyjątkowego wewnętrznego.
Jeżeli będzie jeszcze INTR to zaczeka do następnego rozkazu.
Powyższe reguły obowiązują po każdym rozkazie nie zależnie od „historii” programu, np. μP w obsłudze przerwania.
W 8086 podczas obsługi NMI pamięta fakt wystąpienia kolejnego aktywnego zbocza na we NMI lecz ponowną obsługę odkłada do momentu zakończenia poprzedniej.
Z układami 8086/88 współpracuje koprocesor (zewn.) 8087. Oba układy korzystają ze wspólnych szyn. Koprocesor oprócz wspólnych linii adres-dane-status odczytuje także z linii QS0-QS1 stan zapełnienia kolejki w celu zapewnienia synchronizacji pracy z μP głównym. Koprocesor może przejąć sterowanie magistralą poprzez logikę RQ/GT (w omawianej aplikacji korzysta z linii RQ/GT1 μP, sam CP umożliwia tworzenie łańcuszka żądań dostępu poprzez dołączenie do następnych układów. W celu zapewnienia synchronizacji wyjście BUSY CP podłączone jest do wejścia TEST μP. Jeżeli teraz za rozkazem zmiennoprzecinkowym mieścimy instrukcje WAIT, to praca μP zostanie wstrzymana aż do zakończenia operacji zmiennoprzecinowej przez CP. 8087 jest też źródłem przerwań (wskutek różnych błędów numerycznych), jego wyjście W dołączone jest zwykle do układu kontrolera przerwań 8259 (i pochodnych), w omawianej aplikacji na oddzielnej kartce. 8086 rozpoczynając prace pobiera zawsze 2 bajty spod lokacji FFFF0 (aktywne linie A0 i BHE, poziom niski). 8088 nie wykorzystuje linii BHE, tak więc po sygnale zerującym na podstawie stanu linii 34 CP dopasowuje szerokość swojej szyny danych i długość kolejki do typu μP. Rozkazy, których KO rozpoczyna się 11011 jest przeznaczony dla zewnętrznych koprocesorów, w związku z tym nie wykonuje go μP. Rozkazy ESC mogą również zawierać w drugim bajcie pola mod i r/m określające położenie argumentu zmiennoprzecinkowego w pamięci (64 bity). Należy pamiętać, że CP ma możliwość wymiany danych wyłącznie z pamięcią, poza drobnymi wyjątkami związanymi z przekazaniem statusu zmiennoprzecinkowego nie ma bezpośredniej komunikacji pomiędzy operacją stało- a zminnoprzecinową. 8087 jest „ułomny”, gdyż nie potrafi samodzielnie wyznaczyć adresu argumentu. Dokonuje tego za niego μP, który po rozpoznaniu kodu rozkazu ESC wykonuje ślepy odczyt początku argumentu (2 bajty dla 8086, jeden bajt dla 8088). Podczas tego cyklu CP przechwytuje adres i może rozpocząć samodzielne działanie po zawieszeniu μP - logika RQ/GT. W przypadku odczytu argument doczytuje wtedy pozostałe bajty, w przypadku zapisu zapisuje cały argument. Linie statusu S0 - S2 w μP i CP są ze sobą zwarte, w CP są to linie dwukierunkowe. CP śledzi status oraz może też go wystawić (tylko status, cykl pobrania, odczytu i zapisu pamięci). Jeżeli w programie z efektów obliczeń CP korzystamy po wystarczająco długim czasie, to możemy świadomie zrezygnować z rozkazu WAIT po instrukcji ESC. Oprócz CP 8087 pojawił się też koprocesor we/wy 8089 - nie rozpowszechnił się.
Logika do krokowania co cykl magistrali:
Powyższy układ realizuje prace krokową co krok magistrali. Impuls ALE występujący na początku każdego cyklu powoduje iż linia READY=0 i μP stawia takty oczekiwania w środek cyklu. Po STEP przerzutnik zostaje wyzerowany, co umożliwia dokończenie cyklu po czym impuls ALE cyklu następnego ponownie uruchamia logikę niegotowości itd. W omawianej aplikacji karty CPU 8088 występuje logika zapewniająca przejście pomiędzy dwukierunkowym RQ/GT0 a klasycznymi liniami HOLD i HLDA na magistrali.
Zabezpieczenie RQ/GT0
W omawianej aplikacji CPU na karcie przy μP zawarty jest układ krokowania wraz z logiką wydłużania każdego cyklu a jeden takt zegara. μP korzysta (tryb max) z kontrolera 8288 i zegara 8284. Kontroler na podstawie statusu podstawowego S0-S2 i zegara wspólnego z μP generuje sygnał ALE (zatrzaskuje w buforach `373 adres) oraz sygnałem DTA i DEN sterujące odpowiednim kierunkiem i efektywnością dwukierunkowego wzmacniacza `245. Dla potrzeb układu we/wy blokowanych w pamięci generowany jest zbiorczy sygnał wyboru CSIO. Karta jest zaopatrzona w rozbudowany układ identyfikacji stanu:
dekodowanie kodu stanu instrukcji ESC
indykacja typu cyklu magistrali ('242)
indykacja stanu kolejki (`139)
indykacja użytego rejestru segmentowego (`139)
Zegar 8284 zawiera oscylator sygnału zegarowego (wytwarza także oprócz CLK sygnał podzielony PCLK i wprost oscylator na wyjściu OSC) a ponadto służy do synchronizacji sygnałów niegotowości i zerującego.
Przykładowa realizacja karty pamięci statycznej 128kB (4×32kB), możliwość relokacji przestrzeni adresowej, logika DTACK, wybór podprzestrzeni adresowej.
Narzucona przestrzeń, użyte układy wymuszają połączenie po dwie kostki w dwóch rzędach. O wyborze rzędu decyduje A16, a w ramach tej linii o aktywności kostki sygnał UDS i LDS, linie adresowe A1÷A15 dołączymy równolegle do wszystkich wejść adresowych pamięci odpowiednio do A0÷A14.
Dla Intela na magistrali są linie
i
. Dlatego konieczna jest modyfikacja układu:
bo
O wyborze rzędu A, B bądź C,D decyduje kolejna linia adresowa A16. Otwarcie odpowiedniego bufora `245 jest natomiast warunkowane wyborem karty i aktywnością odpowiedniego strobu danych (górny bądź dolny). Taka sama sytuacja następuje w przypadku sterowania wejść
i
. Są one ustawiane „czasowo” strobami danych natomiast o wyborze OE lub WE decyduje linia kierunku
. Wybór OE bądź WE następuje równocześnie dla kostek A, C lub/i kostek B,D jednakże tylko jedna z powyższych par podejmie działanie - zależy to od stanu na linii A16.
Ze względu na cykle odczytu, modyfikacji, zapisu inicjacja logiki przeterminowania musi być uzależniona od strobów danych. Stroby danych przechodzące przez kartę CPU i logikę naszej karty ulegają naturalnemu opóźnieniu. W przypadku odczytu jest to nawet zjawisko pożyteczne, ponieważ mamy pewność, że w czasie gdy μP czyta dane, bufory naszej karty będą jeszcze otwarte. W przypadku zapisu jeżeli jeszcze strob danych jest równoznaczny z ich ważnością, opóźnienie to spowoduje, że pamięć w momencie zapisu (narastające zbocze na
) otrzyma nieważne (przypadkowe) dane. Efekt ten można wyeliminować skracając na karcie stroby zapisu tzn. wycofując ich aktywny poziom już od momentu wystawienia potwierdzenia transmisji (zwykle wiąże się to z wydłużeniem czasu akceptacji).
Tryb wirtualny procesorów Intela.
W trybie wirtualnym rejestry segmentowe zamiast adresów początkowych segmentów (tryb rzeczywisty) zawierają numery segmentów (13 bitów). Numer ten jest indeksem do tabeli gromadzącej opisy poszczególnych segmentów (kodu, stosu, danych) każdorazowo adres tzw. logiczny musi być odnoszony do aktualnej bazy segmentu (jego adresu początkowego) aby utworzyć adres fizyczny. Opis zawiera również rozmiar segmentu (limit), a także atrybuty (tj. prawa dostępu). Każdorazowo P musi także porównać adres logiczny z limitem i sprawdzić wg atrybutów czy dostęp jest możliwy (ew. generowanie wyjątków).
W związku z konicznością ciągłego odnoszenia adresu logicznego do bazy i porównywania z limitem μP przechowuje opis segmentu w rejestrach ukrytych skojarzonych z rejestrem segmentowym. Rozkaz zapisu do rejestru segmentowego skutkuje automatycznie operacją załadowania opisu segmentu do rejestrów ukrytych.
Adres początku tablicy opisu i jej rozmiar zawiera nowy rejestr GDTR.
W zainstalowanej pamięci zwykle nie mieszczą się wszystkie segmenty wykonywanych zadań. W opisach segmentów nie znajdujących się w pamięci ustawiany jest bit P=0 w polu atrybutów. Jeżeli μP zacznie ładować taki opis to zgłosi wyjątek braku segmentu. Jego obsługa będzie polegała na załadowaniu segmentu z pamięci zewnętrznej do wolnego obszaru, a następnie w odnośnym opisie zostanie ustawiony bit P i zaktualizowana wartość bazy (dawniej segment ten mógł znajdować się w zupełnie innym miejscu). Po powrocie z obsługi tego wyjątku (IRET) μP wznowi wykonanie tej instrukcji i poprawnie załaduje opis segmentu.
Przy każdorazowym załadowaniu segmentu μP ustawia w polu atrybutów bit A=1 (segment użyto). System operacyjny przeglądający cyklicznie tablicę z opisami sporządza statystykę używalności segmentów na podstawie której może usuwać segmenty dawno bądź rzadko używane. Po każdym przeglądzie system zeruje wszystkie bity A. Usunięcie segmentu to wyzerowanie bitu P w jego opisie. W trybie wirtualnym zawartość rejestru segmentowego określa się mianem selektora natomiast opis to deskryptor.
Wielokrotne --> [Author:RD] operacje ściągania z pamięci zewnętrznej potrzebnych segmentów prowadzą w konsekwencji do defragmentyzacji nie zajętego obszaru. W konsekwencji mimo dużej ilości wolnej pamięci brakuje wystarczająco dużego ciągłego obszaru, w którym można by umieścić następny segment. Można przeciwdziałać temu zjawisku poprzez zainicjowanie wbudowanego w μP (począwszy od `386) mechanizmu stronicowania (stronicowanie może zostać włączone jedynie w trybie wirtualnym i na stronie tzw. transparentnej). Intel dzieli teraz wszystkie segmenty na strony o stałej 4kB wielkości. Ściągany z dysku segment jest zapisywany stronami w wolne, niezajęte strony, co pozwala na efektywne wykorzystanie zainstalowanej pamięci. Jednakże μP musi teraz dysponować opisami położenia kolejnych stron w segmencie. Opisy te mieszczą się w tzw. tablicach translacji, zajmują one część pamięci RAM, struktura dwupoziomowa.
W opisie strony znajdują się m.in. poznane bity P oraz A, lecz także opis zawiera bit D informujący o tym czy strona została zmieniona (operator zapisu). Obecność tego bitu pozwala na gospodarkę zasobami na poziomie strony m.in. można zapamiętywać na nośniku zewnętrznym tylko strony zmienione, natomiast te które w opisie nie mają ustawionego bitu D mogą być kasowane bez strat (przez wpis 0 do bitu P w opisie strony).
W zależności od typu μP we wnętrzu zapamiętywana jest pewna ilość opisów ostatnio używanych stron na zasadzie pamięci asocjacyjnej, tak więc μP zanim sięgnie do zewnętrznych tablic translacji sprawdza czy nie dysponuje opisem danej strony w powyższej tabeli.
Począwszy od `286 wprowadzono 4 poziomy uprzywilejowania:
„0” - systemowy (najważniejszy, wewnętrzny)
„1” -
„2” -
„3” - zewnętrzny (domyślny dla użytkownika).
Generalnie obowiązuje zasada, że przy dostępie do kodu możemy sięgać do procedur własnego poziomu i poziomów lepszych (wyższych), w przypadku danych możemy korzystać z danych poziomu własnego i danych poziomów gorszych. Np. użytkownik może korzystać z procedur systemowych, ale nie ma dostępu do danych systemowych (tablice translacji itp.). Istnieją instrukcje uprzywilejowane, które mogą być wykonywane wyłącznie na poziomie zerowym. Po resecie, gdy μP pracuje w trybie rzeczywistym obowiązuje zerowy poziom uprzywilejowania.
W związku z 4 poziomami uprzywilejowania muszą być zdefiniowane 4 segmenty stosu, dla każdego poziomu (wartość SS - selektor i bieżące przesunięcie ESP). Przy przejściu na inny poziom uprzywilejowania musimy dokonać przełączenia stosu np. wywołując procedurę z poziomu niższego przed zapisem na nowym stosie adresu powrotnego musimy tam umieścić opis stosu starego ??? (w postaci SS, ESP).
μP Intela są organicznie przystosowane do pracy w systemach wielozadaniowych (np. na zasadzie obiegania). Ponieważ przełączanie zadań następuje wtedy często, należałoby więc wielokrotnie zachowywać stan startowy rejestru w przypadku zadania inicjalizowanego. Metoda wykorzystująca rozkazy PUSH i POP jest w tym wypadku mało efektywna więc wprowadzono procedury dotyczące wszystkich rejestrów (PUSHA, POPA). W celu szybkiego przełączenia zadań zdefiniowano tzw. segment stanu zadania TSS. Każde z zadań dysponuje takim segmentem a w globalnej tablicy deskryptorów GDT ulokowane są ich opisy (baza, limit, atrybuty).
Numer aktualnego zadania zapisywany jest do rejestru TR, a do rejestrów ukrytych z nim skojarzonych μP automatycznie ładuje z tablicy GDT opis odnośnego TSS'a (odbywa się to przeważnie w trakcie przełączania zadań); samodzielne manipulowanie zawartością TR nie jest zalecane.
W TSS m.in. znajdują się pola, w których zapisany jest stan rejestrów lokalnych μP w momencie zawieszenia danego zadania.
W polu atrybutów każdego TSS'a znajduje się informacja o tym czy dany segment stanu zadania (tzn. samo zadanie) jest dostępne czy zajęte. Jako zadanie niedostępne rozumiemy to zadanie, które jest aktualnie wykonywane przez μP. W momencie przełączania zadań atrybut zajętości uzyskują dwa zadania (zaniechane i inicjowane). Ponadto jeżeli dane zadanie do swojej obsługi wywołuje inne zadanie to oba oznaczane są jako zajęte. Zapobiegamy w tym wypadku możliwości wstecznego wywołania. Powyższe zasady w sposób naturalny umożliwiają budowę systemu wieloprocesorowego, każdy μP korzysta oczywiście ze wspólnych zasobów pamięciowych, a system dysponuje wspólną magistralą. Arbiter magistrali powoduje przekazywanie sterowania kolejnemu μP zabierając magistralę poprzedniemu (zwykle co kilkadziesiąt μs). Powyższe zasady (zajętość/dostępność) powodują, że dane zadanie może obsługiwać maksymalnie 1 procesor, nie dojdzie też do sytuacji, gdy drugi procesor sięgnie do zadania aktualnie zawieszonego, ale tego które wywołało inne zadanie obsługiwane aktualnie przez inny CPU.
Aby separacja μP do poszczególnych zadań była szczelna wprowadzono blokadę zwrotu magistral na czas kontaktu μP z danymi systemowi, to jest opisami segmentu i tablic (aktywna linia wyjściowa LOCK).
Oprócz rejestrów segmentowych, rejestr TR, istnieje rejestr do którego zapisujemy tzw. selektor i który dysponuje rejestrami ukrytymi. Jest to rejestr LDTR tj. rejestr lokalnej tablicy deskryptorów. Dane zadanie może w ogólnym przypadku korzystać z segmentów, których opisy znajdują się w tablicy tylko dla niego przeznaczonej (lokalnej). Położenie rejestrów tablicowych, rozmiar i atrybuty dostępu umieszczone są w tablicy globalnej po zapisie rejestru LDTR instrukcją bądź w trakcie przełączania zadań μP automatycznie uaktualnia z tablicy globalnej zapis w rejestrach ukrytych przy rejestrze LDTR.
Selektor zapisywany do rejestru segmentowego na 13 bitach podaje indeks do tabeli z opisami (dwa bity atrybutów), a na ostatnim indeks tablicy (globalna bądź lokalna). Istnieje możliwość dzielenia pewnych segmentów przez różne zadania - identyczne opisy różnych tablic lokalnych. Pewne zadania mogą mieć wspólne tablice lokalne itp. Położenie tablicy globalnej natomiast oznaczane jest w rejestrze GDTR (32 bity bazy, 16 bitów limitu, brak atrybutów).
W trybie rzeczywistym tablica stanów wyjściowych i przerwań (zawsze 256-cio pozycyjna) zawierała po 4 bajty dla każdego przerwania bądź stanu wewnętrznego (CS, IP). W trybie wirtualnym dla każdego stanu wewnętrznego (jest ich coraz więcej) i przerwań przeznaczono 8 bajtowy deskryptor systemowy. Dlatego też tablica w tym trybie może zawierać maksymalnie 2kB. Położenie tablicy w trybie wirtualnym (baza - limit) określa zawartość rejestru IDTR. Po wyzerowaniu wskazuje on bazę zerową i 1 kB-owy limit (dla trybu rzeczywistego).
W tablicy deskryptorów wyjątków, przerwań można umieszczać wyłącznie deskryptory systemowe bram:
zadania
pułapki
przerwania
Nowo wprowadzone segmenty F i G dotyczą danych i są wykorzystywane oczywiście z odnośnymi przedrostkami. Rejestr bitów warunkowych uległ dalszemu rozszerzeniu a ponadto wprowadzono rejestr CR0 - sterujący pracą μP
Z mechanizmem stronicowania związane są rejestry:
CR3 - podaje adres tablicy translacji 1 stopnia
CR2 - do niego μP zapisuje opis strony w przypadku stwierdzenia błędu stronicowania.
W segmencie TSS μP przechowuje wszystkie tzw. rejestry lokalne (A, B, C, D, SI, DI, BP, SP, IP, flagi, TR, a także LDTR i CR3).
Oznacza to, że dane zadanie może (nie musi) dysponować własnymi tablicami translacji przy stronicowaniu. Podczas wykonywania zadania zawartość LDTR i CR3 nie może i nie ulega zmianie. Dlatego też w procesie przełączania zadań rejestry te nie są zachowywane tylko zawsze odtwarzane dla zadania nowo zainicjowanego.
Organizacja pamięci i wyznaczanie adresu fizycznego.
Pamięć jest podzielona na segmenty logiczne składające się z 64kB każdy. Są one umieszczone w fizycznej 1MB-towej przestrzeni adresowej. Dzięki takiej strukturze jest możliwe tworzenie i umieszczanie programów w pamięci w sposób modułowy. Konkretna komórka pamięci jest adresowana za pomocą dwóch 16-bitowych składników adresu logicznego. μP przetwarza adres logiczny komórki pamięci na rzeczywisty 20-bitowy adres fizyczny.
Adres logiczny komórki pamięci składa się z:
adresu początkowego segmentu, w którym znajduje się ta komórka,
odległości tej komórki od adresu początkowego segmentu (ang. Offset).
Adresy początkowe segmentów pamięci są zawarte w rejestrach segmentowych. Informację o odległości od adresu początkowego segmentu mikroprocesor uzyskuje w różny sposób w zależności od rodzaju operacji pamięciowych oraz od przyjętego w danym rozkazie trybu adresowania. Dla większości operacji pamięciowych odległość ta znajduje się w odpowiednim rejestrze. Dla pozostałych operacji odległość tę należy obliczyć (adres efektywny).
Na podstawie adresu logicznego μP oblicza się adres fizyczny - przesuwa się adres początkowy segmentu o cztery miejsca w lewo i do tak utworzonej wartości dodaje odległość komórki pamięci od adresu początkowego segmentu.
Źródła danych do obliczenia adresu fizycznego.
Rodzaj operacji pamięciowych |
Segment w rejestrze - zazwyczaj |
Segment w rejestrze - inne możliwości |
Offset w rejestrze lub obliczany z: |
Pobranie rozkazu |
CS |
- |
IP |
Operacje na stosie |
SS |
- |
SP |
Pobranie łańcuchów |
DS. |
CS,ES,SS |
SI |
Umieszczanie łańcuchów |
ES |
- |
DI |
Jako rej bazowego w adresie efektywnym danej użyto wskaźnika BP |
SS |
CS,DS,ES |
przemieszczenia, SI, DI, BX, BP |
Jako rej bazowego w adresie efektywnym danej użyto wskaźnika BX |
DS |
CS,ES,SS |
przemieszczenia, SI, DI, BX, BP |
Pamięć jest podzielona fizycznie na dwa bloki, każdy o pojemności maksymalnie 512Kb. Jeden blok jest podłączony do mniej znaczącego bajtu linii danych(D0-D7) i jest adresowany liniami A1-A19. Blok ten jest wybierany wówczas, gdy bit adresu A0 jest równy zero, czyli dla wszystkich adresów parzystych. Drugi blok jest przyłączony do linii danych D8-D15 i obejmuje wszystkie adresy nieparzyste. Jest on wybierany sygnałem sterującym BHE i podobnie jak pierwszy blok, adresowany liniami A1-A19. Jeżeli BHE=1, to jest realizowany dostęp do bloku pamięci z adresami nieparzystymi. Procesor może mieć dostęp do:
mniej i bardziej znaczącego bajtu 16-bitowego słowa z parzystym adresem pierwszego bajtu (A0=0,BHE=0)
mniej znaczącego bajtu 16-bitowego słowa z parzystym adresem lub pojedynczego bajtu z adresem nieparzystym (A0-1, BHE=0)
bardziej znaczącego bajtu 16-bitowego słowa z nieparzystym adresem lub pojedynczego bajtu z adresem nieparzystym (A0=0,BHE=1)
Dostęp do 16-bitowego słowa w jednym cyklu maszynowym jest możliwy tylko wtedy, gdy mniej znaczący bajt jest pod adresem parzystym, a bardziej znaczący pod adresem następnym (nieparzystym).
Segmenty pamięci.
μP rozróżnia następujące dwubitowe pola informacyjne o poziomie uprzywilejowania:
CPL - bieżący
DPL - deskryptora
RPL - selektora
IOPL - układów we/wy.
Poziom CPL nie jest uwidoczniony w żadnym rejestrze, ma go natomiast μP i używa do sprawdzenia możliwości dostępu wg odpowiednich reguł (ogólne zasady podane wcześniej). Wartość CPL jest w zasadzie zawsze ładowana z pola DPL segmentu kodu (program decyduje czy poziom uprzywilejowania programu decyduje o poziomie bieżącym). W przypadku dostępu do segmentu danych musi oczywiście obowiązywać nierówność
, ponieważ np. użytkownik nie może zmieniać ani odczytywać danych systemowych. Aby nie mógł tego uczynić również metodą pośrednią (wywołując procedurę systemową o wysokim priorytecie) w selektorze wywołującym wprowadzono dodatkowe pole RPL, które musi spełniać identyczną nierówność
Pole IOPL decyduje o możliwości dostępu do przestrzeni we/wy na danym poziomie bieżącym, począwszy od `386 wprowadzono także możliwość dostępu selektywnego do poszczególnych lokacji we/wy w danym zadaniu poprzez umieszczenie w jego TSS bitowej tablicy zezwoleń (każda lokacja we/wy 1 bit - 0 zezwolenie, 1 brak zezwolenia)
Opis segmentu pamięci zawiera 32-bitową bazę (adres początkowy), może zmieniać się w czasie pracy systemu, przy włączonym stronicowaniu jest to oczywiście adres liniowy). Rozmiar segmentu określamy na 20 bitach, jeśli G=0 to możemy zdefiniować rozmiar 1MB, a dla G=1 LSB limitu wynosi 4kB stąd wynika maksymalny rozmiar 4GB.
Bit AVL jest przeznaczony dla programisty i przy operacjach na deskryptorach jest nie zmieniany przez μP.
Wśród typów segmentów pamięci pojawiają się pojęcia segmentu rozszerzalnego w dół oraz segmentu zgodnego (dotyczy kodu). Segment rozszerzalny w dół stosuje się dla segmentu stosu.
Zasada, że DPL segmentu kodu określa nam bieżące CPL nie ma zastosowania jedynie dla tzw. zgodnych segmentów kodu. Segment taki nie zmienia zastanego CPL wszelkich przy dostarczaniu do niego obowiązują zwykłe zasady (wywoływanie procedur poziomu własnego bądź lepszego). Aby rozszerzyć skalę dostępu (np. zapis segmentu kodu) można zdefiniować dualny opis tego segmentu różniący się tylko polem typu (możliwość odczytu i zapisu).
Bit D precyzuje domyślny rozmiar bitowy w danym segmencie. W przypadku segmentu kodu oznacza to wybór pomiędzy zestawem 32 bity i 8 bitów bądź 16 i 8 bitów dotyczących adresów argumentów i przesunięć. Możliwe jest zawsze wymuszenie przed danym rozkazem zmiana interpretacji przez odpowiednie przedrostki: rozmiar argumentu #66 i rozmiaru adresu #67.
W segmencie stosu bit D określa nam zastąpienie rejestru ESP bądź SP. Aby deskryptor mógł być odczytany numer zawarty w selektorze (pozycja do tabeli GDT) nie może przekraczać limitu zapisanego np. w rejestrze GDTR. Po odczytaniu deskryptora, jeśli jest on poprawny (S=1, P=1), zostaje on dopiero wtedy zapisany do rejestrów ukrytych, a μP odsyła z powrotem 2 bajty zawierające atrybuty z ustawionym bitem A. Całość operacji w deskryptorze odbywa się przy zablokowanej możliwości zwrotu magistrali (LOCK=1).
Zastosowanie
Olivetti M24 i Compaq Deskpro, typowy przykład mikrokomputerów zgodnych z IBM PC , bazujących na mikroprocesorze Intel 8086.
T1200, laptop, nie odbiega swymi właściwościami od komputerów klasy PC. Jest to 16-bitowy komputer z procesorem 8086 i pamięcią operacyjną 1024 kB. W jego skład wchodzi dysk elastyczny 3,5” i twardy dysk3,5” 20 MB. Odchylany ekran LCD mieści 25 linii po 80 znaków. Może współpracować bezpośrednio z dołączonym kolorowym monitorem.
Robotron A 7150, jest to 16-bitowy komputer osobisty, wyposażony w pamięć główną 768 kB, kompatybilny z IBM PC.
Literatura.
Henryk Małysiak, Bolesław Pochopień, Eugeniusz Wróbel, Mikrokomputery klasy IBM PC
Antoni Niederliński, Mikroprocesory, mikrokomputery, mikrosystemy
Piotr Metzger, Anatomia PC
Zasoby internetowe.
Projekt z przedmiotu Technika Mikroprocesorowa, S.Z., Inf, sem VIII
2
Szukasz gotowej pracy ?
To pewna droga do poważnych kłopotów.
Plagiat jest przestępstwem !
Nie ryzykuj ! Nie warto !
Powierz swoje sprawy profesjonalistom.
Szukasz gotowej pracy ?
To pewna droga do poważnych kłopotów.
Plagiat jest przestępstwem !
Nie ryzykuj ! Nie warto !
Powierz swoje sprawy profesjonalistom.
wykład nr 16 28.04.99
wykład nr 19 12.05.99
Tryb minimalny |
|
Tryb maksymalny |
HOLD |
≡ |
RQ/GT0 |
HLDA |
≡ |
RQ/GT1 |
WR |
≡ |
LOCK |
M/IO |
≡ |
S2 |
DT/R |
≡ |
S1 |
DEN |
≡ |
S0 |
ALE |
≡ |
QS0 |
INTA |
≡ |
QS1 |
4
+
Adres fizyczny
19
16
0
15
Rejestr segmentowy
Adres logiczny
+
FFFF0
FFFF
0000
- adres końcowy
- adres początkowy
1
+
FFFF
FFFF
0FFEF
+
FFFF
0000
FFFF0
- pozostałe
- kod
FFFFF
FFFF0
00000
0FFFF
0FFEF
numer
nr
K.O.
INT
K.O.'
INT 3
(MOD, R/M):DS REG
(adres) (do rejestru wskazanego przez REG)
DS dla LDS
(MOD, R/M+2):DS rejestr segmentowy
ES dla LES
SCAS
CMPS
(#F3)
(#F2)
REPNZ - aż do CX=0 lub Z=1
REPZ - aż do CX=0 lub Z=0
OUTS
INS
MOVS
STDS
REP
(#F3)
MOVSW - słowo
MOVSB - bajt
MOVS
* - występuje od 80186
(LODS) - nie ma sensu z przedrostkiem powtórzenia
_ - nie może ulec zmianie
CMPS
(DI:ES)
(SI:DS)
+
SCAS
-
-
+
In/out
(DX)
OUTS*
INS*
STDS
(LODS)
A
MOVS
To wtedy po przerwaniu zaraz wyjdzie z bloku
Na stos zostaje położony adres (-1). Np. przy przerwaniu, czyli wtedy już po powrocie z przerwania P odda magistralę
2) adres:
(-2) REP
(-1) LOCK
() MOVSB
1) adres:
(-2) LOCK
(-1) REP
() MOVSB
Przerwanie
W P:
I=0
T=0
T=0
I=1
Adres nast. instrukcji
STOS
Śledzenie
W P:
I=0
T=0
T=1
I=x
Adres nast. instrukcji
STOS
Warstwa I
Warstwa II
T=0
I=0
Adres pocz. obsługi przerwania
Przerwanie podczas śledzenia
W P:
I=0
T=0
T=1
I=1
Adres nast. instrukcji
STOS
+
READY
STEP
+
+
+
RUN
OC
ALE
Q3
L
Q2
Q1
Q0
zakłócnie
CLK
HOLD
CLK 8086
+
Q
+
D
Q0
Q1
Q2
Q3
|
DIR |
|
1 0 0 |
x 1 0 |
A,B : wysoka imp. A -> B B -> A |
DIR
G
B
A
Bufor
LS245
Pamięć
WE
OE
CE
D0:7
A14
A0
Pamięć
R/W = DIR
ta linia zawsze jest na magistrali
sterowanie
DB0÷15
B
A
`245
DIR
GBD
B
A
`245
DIR
GAC
połączenie równoległe
0
7
D
WED
OED
CED
A14
A0
0
7
B
WEB
OEB
CEB
A14
A0
8
15
C
WEC
OEC
CEC
A14
A0
A15
A1
8
15
A
Pamięć
WEA
OEA
CEA
A14
A0
FC2
FC1
FC0
wybór przestrzeni
GBD
GAC
CEC,D
CEA,B
Komparator, dekoder
A16
LDS
UDS
K
„=”
+
+
AS
A22
A21
A20
A19
A18
A17
`682
WEB,D
OEB,D
WEA,C
OEA,C
UDS
LDS
R/W
DTACKL
DTACK
DTACKL
OC
CLK
R
Z
LDS
UDS
przesunięcie w czasie
P
karta
zamknięcie buforów
odczyt przez P
DS
Odczyt
WE
DTACK
Rozwiązanie - skrócenie strobu zapisu
problem przy zamknięciu buforów
dane
ale czasem się zdarza, że:
dane
prawidłowo
P
karta
zamknięcie buforów
DS
Zapis
Segment normalny
Segment rozszerzalny w dół
64kB D=0
4 GB D=1
wyjątek - należy zmniejszyć limit
segment
początkowe ESP
baza
limit
segment
np. EIP -> wyjątek segmentu
baza
limit