Intel 8086
8086 – 16-bitowy mikroprocesor wprowadzony na rynek 8 czerwca 1978 roku[1]. Miał także oznaczenia: 8086-1, 8086-2, 8086-4[2], iAPX 86/10[3], a dla wykonywanych w technologii CMOS: 80C86, 80C86-2[4], 80C86A[5].
Mikroprocesor został zaprojektowany przez firmę Intel w technologii 3 μm[6] HMOS (ang. High performance MOS, później także HMOS-II, HMOS-III[7] i CHMOS[4]) jako rozszerzenie 8-bitowego 8080/8085[8]. Wykonywany głównie w obudowach 40-pin DIP[9], także jako 44-pin PLCC[10] i 56-pin QFP (ang. Quad Flat Package). Wciąż jeszcze produkowany przez różnych dostawców[9].
Jego zastosowanie (w szczególności jego późniejszej odmiany z 8-bitowym interfejsem – 8088) w pierwszych ogólnodostępnych komputerach osobistych (IBM PC), doprowadziło do jego wielkiej popularyzacji i dalszego rozwoju tej rodziny procesorów (architektura x86). W związku z historycznym znaczeniem procesora 8086 firmie Intel przydzielono identyfikator 0x8086 na liście identyfikatorów (PCI ID) dostawców urządzeń dla magistrali PCI[11][12].
Geneza
edytujPrace projektowe nad 8086 w firmie Intel rozpoczęto w maju 1976 roku, kiedy projekt przygotowujący 32-bitowy mikroprocesor 8800 napotkał duże trudności[13]. Uruchomienie prac nad nową konstrukcją było ważne dla firmy, gdyż w lipcu 1976 roku ZiLOG utworzony przez byłych pracowników Intela dostarczył Z80, który przewyższał dotychczasowy popularny model Intel 8080.
Charakterystyka
edytujPodstawowe parametry mikroprocesora 8086:
- architektura CISC,
- przestrzeń adresowa pamięci – 1 MB w trybie rzeczywistym,
- 16-bitowa magistrala danych,
- 20-bitowa magistrala adresowa,
- częstotliwość sygnału zegarowego do 10 MHz,
- 91 podstawowych typów rozkazów,
- przestrzeń adresowa urządzeń wejścia/wyjścia – 64 kB,
- możliwość wykonywania operacji bitowych, bajtowych, o długości słowa i łańcuchowych,
- 7 trybów adresowania argumentów w pamięci,
- dwa tryby pracy – minimalny i maksymalny,
- 16-bitowa jednostka arytmetyczno-logiczna (ALU),
- 16-bitowe rejestry ogólnego przeznaczenia,
- 6-bajtowa kolejka rozkazów.
Przy projektowaniu mikroprocesora 8086, konstruktorzy firmy Intel zastosowali wiele nowych, nie występujących w mikroprocesorach 8-bitowych, rozwiązań:
- rozszerzenie możliwości adresowanie operandów
- w mikroprocesorach 8-bitowych, zazwyczaj stosowano cztery tryby adresowania: rejestrowy, natychmiastowy, pośredni i bezpośredni. W mikroprocesorze 8086 dodano rejestry indeksowe (2 rejestry), wskaźnikowe (2 rejestry) i bazowy (1 rejestr), wprowadzając tryby adresowania: indeksowy, bazowy i indeksowo-bazowy.
- wprowadzenie segmentacji obszaru pamięci
- celem rozdzielenia obszarów przeznaczonych dla programu, danych i stosu wprowadzono mechanizm segmentacji. Mikroprocesor zawiera cztery rejestry segmentowe, w których przechowywane część segmentowa adresu. Zawartości tych rejestrów wraz z adresem efektywnym, obliczanym przez mikroprocesor w zależności od trybu adresowania, stanowi adres fizyczny pamięci. Taki sposób adresowania ułatwia relokację programów i danych oraz umożliwia stworzenie prostego mechanizmu zarządzania pamięcią.
- mechanizmy przyspieszenia pracy
- wykonywanie rozkazu przez mikroprocesor można podzielić na kilka etapów. Część z nich wymaga współpracy mikroprocesora z pamięcią (pobieranie kodu operacji, odczyt i zapis argumentu operacji) pozostałe mikroprocesor wykonuje niezależnie (dekodowanie kodu operacji, wykonywanie operacji). W związku z tym projektanci firmy Intel stworzyli dwie osobne jednostki: wykonawczą oraz interfejsową. Pierwsza z nich odpowiedzialna jest za dekodowanie i wykonanie operacji, druga za współpracę z pamięcią. Dzięki takiej architekturze 8086 jest w stanie w jednocześnie wykonywać operację jednego rozkazu oraz pobierać kod operacji następnego
- mechanizmy dla pracy wieloprocesorowej
- mikroprocesor 8086 może pracować w dwóch różnych trybach. W trybie minimalnym steruje on całym systemem mikrokomputerowym pełniąc rolę kontrolera magistrali. Zwykle system taki składa się z jednego obwodu drukowanego i kilku urządzeń peryferyjnych. W trybie maksymalnym magistrala jest współdzielona pomiędzy mikroprocesor a procesory wspomagające. Funkcje sterownika magistrali przejmuje wtedy osobny element systemu mikrokomputerowego zwany kontrolerem magistrali. Tryb ten stosowany jest w przypadku systemów wieloprocesorowych (np. system w którego skład wchodzi mikroprocesor wraz z koprocesorem matematycznym)
Topologia, opis i przeznaczenie końcówek
edytujWyprowadzenia, których funkcja pozostaje taka sama bez względu na tryb pracy mikroprocesora:
- → MN/~MX (Minimum/~Maximum) – stan tego wejścia wyznacza tryb pracy mikroprocesora.
- 1 (Vcc) – powoduje, że mikroprocesor pracuje w trybie minimalnym.
- 0 (GND) – w trybie maksymalnym.
- → CLK – (Clock) sygnał zegarowy, wyznaczający podstawowy takt pracy mikroprocesora. Jest sygnałem asymetrycznym o optymalnym współczynniku wypełnienia 33%.
- → READY – sygnał potwierdzenia gotowości pamięci lub urządzenia wejścia/wyjścia do zakończenia transmisji danych. Jest synchronizowany sygnałem zegarowym.
- → RESET – wystąpienie wysokiego poziomu tego sygnału przez okres co najmniej 4 taktów zegara powoduje natychmiastowe wstrzymanie pracy mikroprocesora, wyzerowanie rejestrów DS, SS, ES, rejestru znaczników (wyłączenie przerwań) oraz wpisanie do rejestru CS wartości FFFFh. Po zaniku sygnału RESET mikroprocesor wznawia pobieranie rozkazów od adresu FFFF0h.
- → INTR – (Interrupt request) Sygnał żądania przerwania. Wejście wyzwalane poziomem, próbkowane w ostatnim takcie zegarowym aktualnie wykonywanego rozkazu. W przypadku gdy sygnał na wejściu jest w stanie aktywnym, a system przerwań odblokowany (ustawiona flaga IF), mikroprocesor rozpoczyna cykl potwierdzenia przerwania (interrupt acknowledge).
- → NMI – (Non–maskable interrupt) wejście wyzwalane zboczem narastającym. Zmiana stanu sygnału z poziomu niskiego na wysoki powoduje zainicjowanie obsługi żądania przerwania po zakończeniu aktualnie wykonywanego rozkazu.
- → ~TEST – (Test) stan tego wejścia jest sprawdzany przez instrukcję WAIT. W przypadku kiedy sygnał wejściowy jest w stanie niskim, mikroprocesor kontynuuje pracę wykonując kolejną instrukcję programu. W przypadku kiedy TEST jest w stanie wysokim, mikroprocesor czeka aż nastąpi zmiana stanu sygnału na niski. Używany do synchronizacji pracy z koprocesorem.
- ↔ od AD0 do AD15 – 16-bitowa, multipleksowana magistrala danych i adresów.
- ↔ A19/S6, A18/S5, A17/S4, A16/S3 – w trakcie pierwszego taktu cyklu interfejsowego dostępu do pamięci są to cztery najbardziej znaczące linie adresu, w przypadku cyklu interfejsowego dostępu do urządzenia wejścia/wyjścia sygnały te wchodzą w stan niski. W pozostałych taktach cyklu interfejsowego, linie te zawierają 4 bity słowa statusu mikroprocesora. Linia S6 ma zawsze wartość logicznego zera, linia S5 zwiera stan flagi blokady systemu przerwań mikroprocesora i jest aktualizowana na początku każdego cyklu zegarowego. Linie S4 i S3 kodują informacje o aktualnie wykorzystywanym segmencie pamięci do tworzenia adresu fizycznego.
S4 | S3 | segment |
---|---|---|
0 0 1 1 |
0 1 0 1 |
dodatkowy (ES) stosu (SS) programu (CS) danych (DS) |
- ← ~BHE/S7 – (Bus High Enable) podczas trwania pierwszego taktu cyklu interfejsowego, sygnał ten informuje czy ma zostać użyty bardziej znaczący bajt magistrali danych. W pozostałych taktach cyklu końcówka pełni funkcję wyjścia sygnału S7 który pozostaje aktywny w stanie niskim. W przypadku wystąpienia żądania przerwania, pozostaje w stanie niskim w pierwszym takcie cyklu potwierdzenia przerwania. Sygnał przechodzi w stan wysokiej impedancji w trakcie stanu zawieszenia mikroprocesora.
- ← ~RD – (Read) sygnał strobujący dla odczytu danych z pamięci lub urządzenia wejścia/wyjścia. W czasie stanu zawieszenia sygnał przechodzi w stan wysokiej impedancji.
Wyprowadzenia, których funkcja zmienia się w zależności od wyboru trybu pracy mikroprocesora:
Znaczenie końcówek dla trybu minimalnego
- ← ~WR – (Write) sygnał strobujący dla zapisu do pamięci lub urządzenia wejścia/wyjścia. W czasie stanu zawieszenia wyjście te wchodzi w stan wysokiej impedancji.
- ← M/~IO – (Status Line) sygnał ten jest odpowiednikiem sygnału S2 (w trybie maksymalnym pracy mikroprocesora). Określa on czy wykonywany cykl interfejsowy dotyczy pamięci czy urządzenia wejścia/wyjścia. W czasie stanu zawieszenia wyjście to wchodzi w stan wysokiej impedancji.
- 1 – dotyczy pamięci
- 0 – dotyczy urządzeń zewnętrznych
- ← ALE – (Address Latch Enable) opadające zbocze tego sygnału, w trakcie trwania pierwszego taktu cyklu interfejsowego, zatrzaskuje adres komórki pamięci lub urządzenia wejścia/wyjścia w zewnętrznych rejestrach.
- ← ~INTA – (Interrupt Acknowledge) sygnał potwierdza wejście mikroprocesora w stan obsługi przerwania. Wykorzystywany jako sygnał strobujący przy wyprowadzeniu wektora przerwań na magistralę danych (podobnie jak sygnał ALE dla cyklów interfejsowych odczytu i zapisu).
- → HOLD – (Hold) sygnał żądania dostępu do magistrali przez urządzenie zewnętrzne (zwolnienia magistrali przez mikroprocesor) np. w celu uzyskania bezpośredniego dostępu do pamięci (DMA).
- ← HLDA – sygnał potwierdzenia zwolnienia magistrali i przejścia mikroprocesora w stan zawieszenia.
- ← ~DEN – sygnał sterujący buforami magistrali danych, otwierający je tylko na czas przesyłania danych przez multipleksowaną magistralę. W czasie stanu zawieszenia wyjście to wchodzi w stan wysokiej impedancji.
- ← DT/~R – sygnał określający kierunek przesyłania danych poprzez bufory
- 1 – transmisja przebiega w kierunku od mikroprocesora do pamięci, bądź urządzeń zewnętrznych
- 0 – wskazuje kierunek do mikroprocesora
- W czasie stanu zawieszenia wyjście to wchodzi w stan wysokiej impedancji.
Znaczenie końcówek dla trybu maksymalnego
- ← ~LOCK – (Lock) sygnał informuje procesor wspomagający (za pomocą stanu niskiego), że żądanie zwolnienia magistrali zostało zablokowane do czasu wykonania instrukcji z prefiksem „LOCK”. W czasie stanu zawieszenia wyjście to wchodzi w stan wysokiej impedancji.
- ← ~S0, ~S1, ~S2 – sygnały te określają rodzaj cyklu interfejsowego wykonywanego przez mikroprocesor.
~S0 | ~S1 | ~S2 | cykl interfejsowy |
---|---|---|---|
0 0 0 0 1 1 1 1 |
0 0 1 1 0 0 1 1 |
0 1 0 1 0 1 0 1 |
potwierdzenie przerwania odczyt z WE/WY zapis do WE/WY zatrzymanie (HALT) pobranie rozkazu odczyt z pamięci zapis do pamięci stan pasywny, brak cyklu interfejsowego |
- ← QS0, QS1 – (Queue Status) sygnały określają stan kolejki rozkazów mikroprocesora. Są one ważne w trakcie trwania taktu zegarowego poprzedzającego wykonanie przez kolejkę określonej operacji.
QS1 | QS2 | stan kolejki |
---|---|---|
0 0 1 1 |
0 1 0 1 |
bez operacji pobranie do wykonania pierwszego bajta rozkazu kolejka pusta pobranie kolejnego bajta |
- ↔ ~RQ/~GT0 oraz ~RQ/~GT1 – (Request/Grant) sygnały te wykorzystywane są do wymuszenia zwolnienia magistrali przez procesor, aktualnie ją zajmujący. Sygnał RQ/GT0 ma wyższy priorytet od sygnału RQ/GT1.
Architektura procesora
edytujMikroprocesor 8086 składa się z dwóch współpracujących zespołów, działających jednocześnie:
- jednostki wykonawczej EU
- jednostki interfejsowej (zespołu łącza z magistralą systemową) BIU
Jednostka wykonawcza
edytujW jej skład wchodzi 16-bitowa jednostka arytmetyczno-logiczna ALU wraz z rejestrem znaczników oraz blok rejestrów ogólnego przeznaczenia. ALU dołączona jest do magistrali wewnętrznej mikroprocesora. Z magistrali tej pobierane są argumenty operacji, a także wysyłany jest na nią wynik operacji.
Rejestr znaczników
edytujBezpośrednio do jednostki arytmetyczno-logicznej dołączony jest 16-bitowy rejestr znaczników (rejestr flag). Znajdujące się w nim flagi zostały podzielone na dwie grupy, tj. kontrolną i arytmetyczną. Flagi arytmetyczne dostarczają dodatkowych informacji na temat wyniku ostatniej operacji wykonanej przez jednostkę arytmetyczno-logiczną. Flagi kontrolne wpływają na sposób pracy mikroprocesora.
Mniej znaczący bajt rejestru znaczników odpowiada rejestrowi znaczników mikroprocesora 8080/8085. Cztery najbardziej znaczące bity pozostają nieużywane.
Znaczenie poszczególnych znaczników jest następujące:
- SF (sign flag) – znacznik znaku – równy najbardziej znaczącemu bitowi wyniku
- 0 – wynik operacji dodatni
- 1 – wynik operacji ujemny
- ZF (zero flag) – znacznik zera
- 0 – wynik operacji różny od zera
- 1 – wynik operacji równy zeru
- PF (parity flag) – znacznik parzystości – ustawiany w zależności od liczby jedynek w najmniej znaczących 8 bitach wyniku
- 0 liczba jedynek w wyniku operacji nieparzysta
- 1 liczba jedynek w wyniku operacji parzysta
- AF (auxiliary carry flag) – znacznik przeniesienia połówkowego (pomocniczego)
- 0 – brak przeniesienia pomiędzy trzecim i czwartym bitem bajta (BCD)
- 1 – występuje przeniesienie
- CF (carry flag) – znacznik przeniesienia
- 0 – wynik operacji arytmetycznej nie powoduje powstania przeniesienia z najbardziej znaczącego bitu
- 1 – wynik takie przeniesienie powoduje
- OF (overflow flag) – znacznik nadmiaru
- IF (interrupt flag) – znacznik przerwań
- 0 – brak zezwolenia na przyjmowanie przerwań z wejścia INT
- 1 – zezwolenie na przyjmowanie przerwań
- DF (direction flag) – znacznik kierunku, wskazuje, czy zawartości rejestrów SI i DI mają być zwiększane lub zmniejszane o jeden w czasie wykonywania operacji łańcuchowych
- 0 – rejestry są zwiększane
- 1 – rejestry są zmniejszane
- TF (trap flag) – znacznik pułapki umożliwiającej pracę krokową
- 0 – praca krokowa wyłączona
- 1 – praca krokowa włączona, mikroprocesor po wykonaniu każdego rozkazu wykona skok do odpowiedniego podprogramu obsługi przerwania.
Rejestry ogólnego przeznaczenia
edytujW skład bloku rejestrów ogólnego przeznaczenia wchodzą rejestry: arytmetyczne, wskaźnikowe oraz indeksowe.
Rejestry arytmetyczne
Są to cztery 16-bitowe rejestry ogólnego przeznaczenia: AX, BX, CX, DX.
Każdy z tych rejestrów może również działać jako dwa niezależne rejestry 8-bitowe:
- AX lub AH, AL
- BX lub BH, BL
- CX lub CH, CL
- DX lub DH, DL
Niektóre z instrukcji mikroprocesora używają rejestrów arytmetycznych do ściśle określonych celów. Zgodnie z przeznaczeniem każdy z rejestrów arytmetycznych ma swoją nazwę:
- AX – Akumulator (Accumulator)
Rejestr ten bezpośrednio współpracuje z jednostką arytmetyczno-logiczną.
Niektóre operacje, których argumenty znajdują się w akumulatorze, wykonywane są szybciej niż ich odpowiedniki wykorzystujące inne rejestry. Takie rozkazy jak: mnożenie, dzielenie i operacje wejścia/wyjścia wymagają użycia akumulatora do przechowywania argumentu bądź też zapisu wyniku.
- BX – Baza (Base)
Rejestr ten może być używany do adresowania argumentu, znajdującego się w pamięci, stanowiąc bazę do obliczania adresu.
- CX – Licznik (Counter)
Rejestr ten jest używany jako licznik w operacjach łańcuchowych oraz pętlach. Po każdej iteracji jego zawartość jest automatycznie dekrementowana. W rozkazach przesunięć, rejestr CL (mniej znaczący bajt rejestru CX), wykorzystywany jest jako licznik bitów.
- DX – Dane (Data)
Rejestr ten jest wykorzystywany w niektórych operacjach arytmetycznych do przechowywania części argumentu lub wyniku operacji (mnożenie i dzielenie 16-bitowe). Zawiera on także adres urządzenia w operacjach wejścia/wyjścia.
Rejestry wskaźnikowe i indeksowe
Są to 16-bitowe rejestry adresowe: SP, BP, SI, DI. Ich głównym zadaniem jest wskazywanie miejsca w pamięci, w którym znajdują się argumenty rozkazu. Wykorzystywane są w adresowaniu indeksowym, bazowym oraz indeksowo-bazowym. Można ich również używać do przechowywania argumentu bądź wyniku operacji. Podobnie jak w przypadku rejestrów arytmetycznych, rejestry adresowe mają nazwy zależne od funkcji jaką pełnią:
- SP – wskaźnik stosu (Stack Pointer).
Wskazuje adres ostatnio zapisanego słowa na stosie. Jego zawartość jest automatycznie inkrementowana lub dekrementowana w zależności od wykonywanej operacji (POP, PUSH).
- BP – wskaźnik bazy (Base Pointer).
Pełni on funkcję wskaźnika ogólnego przeznaczenia. Wykorzystywany jest do adresowania bazowego danych w segmencie stosu.
- SI – rejestr indeksowy źródła (Source Index).
Uniwersalny rejestr indeksowy. Jest wykorzystywany w czasie dwuargumentowych operacji łańcuchowych do przetrzymywania adresu źródła danych. Po każdej kolejnej iteracji jego zawartość jest inkrementowana lub dekrementowana, zależnie od ustawienia flagi kierunku.
- DI – rejestr indeksowy przeznaczenia (Destination Index).
Uniwersalny rejestr indeksowy. Jest wykorzystywany w czasie dwuargumentowych operacji łańcuchowych do przetrzymywania adresu przeznaczenia danych. Po każdej kolejnej iteracji jego zawartość jest inkrementowana lub dekrementowana, zależnie od ustawienia flagi kierunku.
Jednostka arytmetyczno-logiczna (ALU)
edytujZajmuje się wykonaniem podstawowych operacji arytmetycznych (dodawanie i odejmowanie) oraz logicznych (np. suma, iloczyn lub negacja logiczna). Mikroprocesor 8086 ma 16-bitową jednostkę arytmetyczno-logiczną, co umożliwia mu szybkie wykonywanie zarówno operacji 8- jak i 16-bitowych.
Jednostka interfejsowa
edytujOdpowiada ona za współpracę z magistralą systemową. Do jej zadań należy odczyt i zapis danych do pamięci oraz urządzeń peryferyjnych. Ponadto jest odpowiedzialna za pobieranie kolejnych rozkazów w pamięci mikroprocesora i umieszczanie ich w kolejce rozkazów.
Rejestry segmentowe
edytujSą to 16-bitowe rejestry, dostępne dla programisty, których zawartość służy do obliczania adresu fizycznego komórki pamięci. Rejestry te zawierają adres początkowy danego segmentu pamięci. Mikroprocesor w zależności od rodzaju segmentu pamięci, do którego chce się odwołać, wykorzystuje odpowiedni z rejestrów. Programista ma możliwość zmiany automatycznie wykorzystywanego rejestru poprzez umieszczenie odpowiedniego prefiksu przed rozkazem, dla którego zmiana ma zostać zastosowana.
- CS – rejestr segmentowy programu (Code Segment register).
Zawartość tego rejestru wyznacza początek aktualnie używanego segmentu programu.
Wartość ta wykorzystywana jest do obliczania adresu fizycznego kolejnego rozkazu do pobrania z pamięci.
- DS – rejestr segmentowy danych (Data Segment register).
Zawartość tego rejestru wyznacza początek aktualnie używanego segmentu danych. Wartość ta wykorzystywana jest do obliczania adresu fizycznego argumentu lub wyniku aktualnie wykonywanego rozkazu. Wyjątek stanowią rozkazy łańcuchowe, w których zawartość tego rejestru służy jedynie do obliczania adresu źródła danych.
- SS – rejestr segmentowy stosu (Stack Segment register).
Zawartość tego rejestru wyznacza początek aktualnie używanego segmentu stosu. Wartość ta wykorzystywana jest do obliczania adresu fizycznego komórki pamięci, na którą wskazuje wskaźnik stosu (rejestr SP).
- ES – rejestr segmentowy dodatkowy (Extra Segment register).
Zawartość tego rejestru wyznacza początek aktualnie używanego dodatkowego segmentu danych. Wartość ta wykorzystywana jest do obliczania adresu fizycznego przeznaczenia dla operacji łańcuchowych (np. rozkazu przenoszenia bloku danych).
Licznik rozkazów (Instruction Pointer – IP)
edytujJest to 16-bitowy rejestr, którego zawartość służy do obliczania adresu fizycznego następnego słowa rozkazu do pobrania z pamięci. Stanowi on rejestr indeksowy dla rejestru CS wyznaczającego segment z kodem programu. Jego zawartość jest automatycznie inkrementowana po pobraniu każdego bajtu rozkazu (w przypadku pobrania słowa jego wartość wzrasta o 2). Programista ma możliwość zmiany zawartości licznika rozkazów poprzez zastosowanie rozkazu skoku.
Generator adresu fizycznego
edytujJest to 20-bitowy sumator służący do obliczania adresu fizycznego komórki pamięci.
Kolejka rozkazów
edytujJest to 6 bajtowa pamięć zorganizowana w słowa (trzy 2-bajtowe komórki) wykorzystywane przez mikroprocesor do przechowywania pobranych wcześniej rozkazów.
Organizacja pamięci i generacja adresu fizycznego
edytujMikroprocesor 8086 ma 20-bitową magistralę adresową. Pozwala ona na zaadresowanie do 1 MB pamięci operacyjnej. Przestrzeń adresowa została podzielona na segmenty o długości 64 kB, rozpoczynające się co 16 bajtów (kolejne segmenty pamięci mogą nakładać się na siebie). Adres fizyczny komórek pamięci obliczany jest na podstawie dwóch 16-bitowych składników tj. adresu segmentu oraz adresu efektywnego (przesunięcia). Taki sposób adresowania nazywa się adresowaniem segmentowym. Na rysunku z prawej pokazano przykładową organizacje pamięci operacyjnej dla mikroprocesora 8086.
Do otrzymania adresu fizycznego stosuje się tzw. generator adresu fizycznego, znajdujący się w jednostce interfejsowej. Adres segmentu mnożony jest przez 16, co powoduje że zostaje on przesunięty o 4 bity w lewo (zwolnione z prawej strony bity przyjmują wartość 0), a następnie dodaje się do niego adres efektywny obliczony z zastosowaniem wszystkich modyfikatorów (w przypadku danych) lub zawartość licznika rozkazów (w przypadku rozkazów).
Przykład generacji adresu fizycznego
Adres logiczny: 0010h:000Fh (adres początku segmentu:wartość przesunięcia (tzw. adres efektywny))
0010h * 0010h (16 dziesiętne) = 00100h (dwudziestobitowy adres początku segmentu)
00100h + 000Fh = 0010Fh (adres fizyczny komórki pamięci)
Niejednoznaczność adresowania segmentowego
Adresowanie segmentowe jest niejednoznaczne (jest to spowodowane nachodzeniem na siebie segmentów), jedna komórka pamięci może mieć kilka adresów logicznych. Zależnie od wyboru segmentu, względem początku którego komórka pamięci będzie adresowana, jej adres logiczny będzie inny. W celu rozwiązania tego problemu stosuje się normalizację adresu logicznego.
Tryby adresowania
edytujTrybem adresowania nazywamy sposób wyznaczania adresu operandu, którego to mianem określamy argumenty i wyniki operacji. W mikroprocesorze 8086 każdy z rejestrów ogólnego przeznaczenia może służyć do przechowywania adresu lub jego składnika. Adres operandu obliczany jest zgodnie z równaniem
gdzie:
- – adres efektywny,
- – rejestr bazowy,
- – rejestr indeksowy,
- – przemieszczenie.
Adres efektywny EA jest adresem logicznym „widzianym” przez program. Na podstawie EA układy segmentacji obliczają adres rzeczywisty w pamięci operacyjnej. Rejestrem bazowym może być rejestr BP lub BX, a rejestrem indeksowym może być rejestr SI lub DI. Przemieszczenie jest zawarte w rozkazie i może mieć długość ośmiu lub szesnastu bitów.
Mikroprocesor 8086 realizuje następujące tryby adresowania:
- natychmiastowe,
- rejestrowe,
- bezpośrednie,
- pośrednie,
- bazowe,
- indeksowe,
- indeksowo-bazowe.
Adresowanie natychmiastowe
edytujW adresowaniu natychmiastowym argument pobierany jest bezpośrednio z rozkazu. W tym trybie wskazywany jest wyłącznie operand źródłowy. Np. MOV AX, 20 – w rejestrze AX zostanie zapisana liczba 20.
Adresowanie rejestrowe
edytujW adresowaniu rejestrowym operandy znajdują się w rejestrach wewnętrznych mikroprocesora. Jeżeli operand znajduje się w pamięci, to zespół wykonawczy EU oblicza jego 16-bitowy adres (przesunięcie) wewnątrz segmentu. Zespół BIU oblicza adres rzeczywisty na podstawie otrzymanego przesunięcia (adresu efektywnego EA) i zawartości wybranego rejestru segmentowego. Np. MOV AX, BX – w rejestrze AX zostanie zapisana zawartość rejestru BX.
Adresowanie bezpośrednie
edytujW adresowaniu bezpośrednim adres operandu znajduje się bezpośrednio w rozkazie. Np. MOV AX, [40] – w rejestrze AX zostanie zapisana zawartość komórki pamięci (segment danych) o adresie 40.
Standardowy adres operandu jest przesunięciem w segmencie danych (DS), można to nadpisać poprzez wskazanie innego segmentu. Np. MOV AX, CS:[40] – w rejestrze AX zostanie zapisana zawartość z komórki pamięci (segment PROGRAMU(kodu)) o offsecie 40.
Adresowanie pośrednie
edytujW trybie adresowania pośredniego odwołujemy się do jednego z rejestrów roboczych procesora (np. BX) lub do komórki pamięci (np. 19). W rejestrze (BX) zapisany jest numer komórki pamięci, do której trzeba sięgnąć aby odczytać tam zawarty adres i przenieść do drugiego rejestru (AX). Dla adresowania pośredniego z pamięci odczytujemy numer komórki pamięci z dwóch komórek (komórki 19 i komórki 20) w taki sposób, że zawartość tej pierwszej (19) stanowi ważniejszą część tego numeru, zaś zawartość drugiej komórki (20) mniej ważną część tego numeru. Dalej postępujemy podobnie jak przy adresowaniu pośrednim z rejestru – przenosimy zawartość do rejestru AX. Np. MOV AX, [CX] – w rejestrze AX zostanie zapisana zawartość komórki pamięci o adresie, który znajduje się w rejestrze CX.
Wszystkie rejestry wskazują offset w segmencie danych (DS), poza rejestrem BP, który jest przesunięciem w segmencie stosu (SS). Można to zmienić określając segment w rozkazie. Np. MOV AX, SS:[CX] – w rejestrze AX zostanie zapisana zawartość komórki pamięci z segmentu stosu o adresie, który znajduje się w rejestrze CX.
Adresowanie bazowe
edytujAdresowanie bazowe jest to rodzaj adresowania pośredniego, gdzie rozkaz wskazuje na jeden z rejestrów bazowych BX lub BP i może zawierać 8- lub 16-bitową wartość stanowiącą lokalne przemieszczenie. Adresem efektywnym jest suma zawartości rejestru bazowego i lokalnego przemieszczenia. Np. MOV AX, [BP+2].
Adresowanie indeksowe
edytujAdresowanie indeksowe jest rodzajem adresowania pośredniego, gdzie adres efektywny jest sumą zawartości rejestru indeksowego SI lub DI i lokalnego przemieszczenia. Np. MOV AX, [SI+3].
Adresowanie bazowo-indeksowe
edytujW adresowaniu bazowo-indeksowym, adres efektywny jest sumą zawartości jednego z rejestrów bazowych, jednego z rejestrów indeksowych i lokalnego przemieszczenia. Np. MOV AX, [SI+BP+4].
Rozkazy operujące na ciągach słów
edytujRozkazy operujące na ciągach słów posługują się rejestrami indeksowymi. Rejestry SI i DI zawierają adresy efektywne pierwszego słowa odpowiednio w ciągu źródłowym i wynikowym. Po każdej transmisji rejestry indeksowe są automatycznie inkrementowane lub dekrementowane w zależności od ustawienia bitu DF w rejestrze znaczników.
Rozkazy operujące na rejestrach WE/WY
edytujRozkazy operujące na rejestrach WE/WY zawierają adres WE/WY (adres natychmiastowy) lub posługują się zawartością rejestru DX (adresowanie pośrednie).
Budowa rozkazu
edytujRozkazy mikroprocesora 8086 można podzielić na następujące grupy:
- arytmetyczno-logiczne
- przesłań
- skoków, obsługi pętli, wywołań i powrotów z podprogramu
- dotyczące rejestrów segmentowych
- wykonujące operacje na ciągach słów
- wejścia/wyjścia
- inne
Rozkazy mikroprocesora 8086 są wielobajtowe. Liczba bajtów każdego rozkazu zależy od jego rodzaju i może wynosić od jednego do sześciu.
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
kod operacji | D | W | |||||
MOD | REG | R/M |
Pierwszy bajt zawiera sześciobitowy kod operacji oraz dwa bity (kierunku i szerokości). Bit D określa kierunek transmisji (0 – wynik operacji jest przesyłany z rejestru do pamięci, 1 – z pamięci do rejestru). W zależności od wartości tego bitu w rozkazie rozróżniane są operandy źródłowe i operandy przeznaczenia. Bit W określa szerokość operandu danego rozkazu (0 – operacje bajtowe, 1 – operacje na słowie 16-bitowym).
Jeżeli rozkaz jest wielobajtowy, to drugi bajt rozkazu określa sposób adresowania argumentów. Zawiera on trzy grupy bitów
- dwubitowa grupa MOD określa tryb adresowania
- trzybitowa grupa REG określa numer rejestru, w którym znajduje się operand
- trzybitowa grupa R/M określa sposób wyznaczenia miejsca operandu
Jeżeli operandy znajdują się w rejestrach mikroprocesora (MOD = 11), to pola REG i R/M stanowią ich numery (odpowiednio pierwszego i drugiego operandu)
REG
R/M |
W = 0 | W = 1 |
---|---|---|
000 001 010 011 100 101 110 111 |
AL CL DL BL AH CH DH BH |
AX CX DX BX SP BP SI DI |
Jeżeli jeden z operandów znajduje się w pamięci, to pola MOD i R/M określają jego adres
R/M | MOD = 00 | MOD = 01 | MOD = 10 |
---|---|---|---|
000 001 010 011 100 101 110 111 |
BX+SI BX+DI BP+SI BP+DI SI DI p16 BX |
BX+SI+p8 BX+DI+p8 BP+SI+p8 BP+DI+p8 SI+p8 DI+p8 BP+p8 BX+p8 |
BX+SI+p16 BX+DI+p16 BP+SI+p16 BP+DI+p16 SI+p16 DI+p16 BP+p16 BX+p16 |
Znaczenie bitów R/M zależy od wartości bitów w polu MOD. Jeżeli MOD != 11, to grupa R/M określa rejestry adresujące. Jeżeli natomiast MOD == 11, to R/M określa rejestr (podobnie jak REG) drugiego operandu. Jeżeli rozkaz tego wymaga, to po drugim bajcie rozkazu może występować jeden lub dwa bajty przemieszczenia. Jeden bajt przemieszczenia występuje w sytuacji, gdy MOD == 01, natomiast przemieszczenie dwubajtowe występuje, gdy MOD == 10.
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
MOD | REG | R/M | kod operacji | D | W | ||||||||||
przemieszczenie | |||||||||||||||
dana |
Rysunek przedstawia format rozkazu sześciobajtowego, gdzie dwa ostatnie bajty to argument natychmiastowy dla tego rozkazu.
Obok omówionego formatu występują także rozkazy jednobajtowe, czego przykładem może być rozkaz wymiany zawartości akumulatora z zawartością wybranego rejestru. W kodzie tego rozkazu pięć bitów stanowi kod operacji, a pozostałe trzy bity wskazują numer rejestru którego ten rozkaz dotyczy.
Współpraca mikroprocesora z pamięcią
edytujRysunek przedstawia zasadę współpracy mikroprocesora z dwoma blokami pamięci o pojemności 512kB każdy, przy czym jeden z nich zawiera bajty parzyste i dołączony jest do szyny D0 – D7, a drugi zawiera bajty nieparzyste (D8 – D15). Bity A0 i ~BHE określają sposób wykorzystania pamięci. Jeżeli A0 == 1 i ~BHE == 0, to korzysta się z bloku A pamięci, który współpracuje z bardziej znaczącym bajtem szyny danych. Jeżeli A0 == 0 i ~BHE == 1, to korzysta się z bloku B pamięci, który współpracuje z mniej znaczącym bajtem szyny danych. Jeżeli natomiast A0 == 0 i ~BHE == 0, to mikroprocesor współpracuje z obydwoma blokami pamięci, przesyłając po szynie słowo szesnastobitowe.
Zobacz też
edytujPrzypisy
edytuj- ↑ 1978. [w:] Microprocessor Quick Reference Guide [on-line]. Intel. [dostęp 2013-08-29]. (ang.).
- ↑ 8086. cpu-info.com. [dostęp 2013-08-29]. [zarchiwizowane z tego adresu (2012-04-01)]. (ang.).
- ↑ iAPX 86, 88 User’s Manual. Intel, 1981-08. [dostęp 2013-08-29]. (ang.).
- ↑ a b M80C86/M80C86-2 Data Sheet. Wyd. 005. Intel, 1989-11. [dostęp 2013-08-29]. (ang.).
- ↑ Gennadiy Shvets: Intel 8086 microprocessor family. CPU-World.com. [dostęp 2013-08-29]. (ang.).
- ↑ Intel486™ Processors and Earlier. [w:] Microprocessor Quick Reference Guide [on-line]. Intel. [dostęp 2013-08-29]. (ang.).
- ↑ 8086 Data Sheet. Wyd. 005. Intel, 1990-09. [dostęp 2013-08-29]. (ang.).
- ↑ The 8086 Family User’s Manual. Intel, 1979-10. [dostęp 2013-08-29]. (ang.).
- ↑ a b 80C86 - CMOS 16-Bit Microprocessor. Intersil. [dostęp 2013-08-29]. (ang.).
- ↑ 80C86 Data Sheet. Intersil, 1997-03. [dostęp 2013-08-29]. (ang.).
- ↑ Intel Corp.. [w:] Vendor Details [on-line]. PCIDatabase.com. [dostęp 2013-08-29]. [zarchiwizowane z tego adresu (2013-07-30)]. (ang.).
- ↑ Vendor 8086. [w:] The PCI ID Repository [on-line]. [dostęp 2013-08-29]. (ang.).
- ↑ Edwards Benj: Birth of a Standard: The Intel 8086 Microprocessor. PC World, 2008-06-16. [dostęp 2013-08-29]. (ang.).