1
Wstęp Stanowisko z mikroprocesorem Intel 8088 Układ 8088 jest wersją mikroprocesora 8086. Zasadniczymi róŝnicami są: - 8- bitowa szyna danych (8086 ma 16- bitową szynę danych) - 4- bajtowa kolejka instrukcji (8086 ma kolejkę 6- bajtową). Pod względem programowym procesory są identyczne. W skład stanowiska laboratoryjnego wchodzą: - karta CPU (8088 + koprocesor 8087) - pamięć RAM 128kB - pamięć startowa- bootsrap (16 bajtów od adresu FFFF0) - konsola - wyświetlacz - symulator przerwań pokazane na rysunku 1.1. Rys.1.1. Struktura stanowiska z mikroprocesorem 8088 Na płycie czołowej CPU moŝna zaobserwować podstawowe sygnały 8088. Przyciski umoŝliwiają m. in. zerowanie, sterowanie linią wejściową TEST, wydłuŝanie kaŝdego cyklu magistrali o 1 takt generatora, zatrzymanie pracy µp. (ciągłe wstawianie taktów oczekiwania do zatrzymanego cyklu) i pracę co pojedynczy cykl magistrali (przycisk wyniesiony). Ponadto moŝna wyłączyć wszystkie diody LED. Pamięć RAM zajmuje lokacje 00000-1FFFFh. Cykl dostępu do pamięci wskazuje czerwona dioda CS na module pamięci. Konsola umoŝliwia dostęp do pamięci RAM po uprzednim zawieszeniu µp. Zawieszenie (na Ŝądanie HOLD z konsoli) polega na tym, Ŝe µp. wprowadza swoje linie w stan wysokiej impedancji co jest sygnalizowane linią HLDA. W trakcie dostępu do pamięci wpisywany jest 2
w postaci heksadecymalnej program (który będzie wykonywał µp.) i odpowiednie wektory (adresy) przerwań. UŜywane w trakcie ćwiczenia przyciski na konsoli obserwacyjno- sterujacek pokazuje rysunek 1.2. Rys.1.2. Konsola sterująca. Mikroprocesor8088/8086 W mikroprocesorach 8088 i 8086 wprowadzono, po raz pierwszy, przyśpieszenie działania poprzez podział procesora na dwie niezaleŝnie działające części: - Jednostkę kontaktu z magistralą (BIU). - Jednostkę wykonawczą (EU). Strukturę blokową mikroprocesora pokazano na rysunku 1.2. BIU jest odpowiedzialne za pobieranie rozkazów z pamięci programu. EU wykonuje rozkazy. W tym samym czasie gdy EU wykonuje kolejny rozkaz, BIU pobiera następne rozkazy. Powoduje to przyśpieszenie działania mikroprocesora. Aby współpraca obu jednostek była dynamiczna (czasy wykonywania rozkazów w procesorach Intel są róŝne), obie części połączono kolejką rozkazów typu FIFO (First Input First Outpt)- pierwszy wszedł- pierwszy wyszedł. W procesorze z 8 bitową szyną danych (8088) kolejka składa się z 4 bajtów, w wersji 16 bitowej (8086) kolejka jest 6 bajtowa. Sposób działania kolejki prezentuje rysunek 1.3. 3
Rys.1.2. Struktura blokowa mikroprocesora 8088/8086. Rys.1.3. Współpraca BIU i EU. W mikroprocesorze 8088/8086 istnieje moŝliwość zaadresowania do 1 Mbajta pamięci (20 linii adresowych A0-A19). Jednak wszystkie rejestry wewnętrzne są rejestrami 16-to bitowymi (w tym: licznik rozkazów, wskaźnik stosu i rejestry indeksowe, słuŝące do adresacji pamięci danych). Dlatego zastosowano tzw. segmentację pamięci. Cały obszar pamięci jest podzielony na segmenty 64 kb-ajtowe. WyróŜniamy cztery segmenty (kodu, stosu, danych i dodatkowy). Dodatkowe cztery bity, potrzebne do określenia miejsca segmentu w pamięci zawierają odpowiednie rejestry segmentowe pokazane w BIU na rysunku 1.3.- CS, SS, DS., ES. Rejestry te są równieŝ rejestrami 16- bitowymi, dlatego adres fizyczny (adres na magistrali adresowej) powstaje przez zsumowanie zawartości rejestru segmentowego przesuniętego o cztery bity w lewo, z odpowiednim rejestrem zawierającym adres efektywny. Mechanizm adresowania pokazuje rysunek 1.4. 4
Rys.1.4. Mechanizm adresowania w procesorze Intel 8088/8086. Przykład tworzenia adresu 12345h w segmencie stosu SS 1 0 0 0 0 W to miejsce µp wpisze cztery bity=0 SP 2 3 4 5 1 2 3 4 5 Adres fizyczny Dla kodu programu rejestrem segmentowym jest CS (Code Segment) oraz licznik rozkazów- IP (Index Program). Dla stosu rejestrem segmentowym jest SS (Stock Segment) oraz wskaźnik stosu SP (Stock Pointer) Dla danych rejestrem segmentowym moŝe być DS (Data Segment) lub ES (Extra Segment) i przykładowo rejestry indeksowe SI (Source Index)- rejestr indeksowy źródła i DI (Destination Index)- rejestr indeksowy przeznaczenia. Segmenty mogą na siebie zachodzić. Ćwiczenie Rozbiegówka Po przyciśnięciu przycisku RESET na konsoli mikroprocesor wystawia adres FFFF0h, spod którego pobiera kod operacyjny (KO) pierwszej instrukcji. Adres ten otrzymuje się przez zsumowanie zawartości rejestru segmentowego kodu CS i wskaźnika instrukcji IP. Są to rejestry 16- bitowe i dodaje się je z 4- bitowym przesunięciem. Po wyzerowaniu µp. CS jest jedynkowany a IP zerowany, podobnie jak pozostałe rejestry segmentowe(stosu- SS, danych- DS., dodatkowy- ES). CS F F F F 0 W to miejsce µp wpisze cztery bity=0 IP 0 0 0 0 F F F F 0 Adres fizyczny Lokacje FFFF0-F (tj. 16- ostatnich adresów przestrzeni pamięci µp.) obejmuje moduł pamięci bootstrap. Nastawione na 16-tu 8- bitowych przełącznikach wartości mogą być wyłącznie odczytywane przez µp. (przycisk AKT na czołówce bootstrap wyciśnięty). Aktualnie w pamięci bootstrap są nastawione następujące rozkazy: 5
Adres Dana Rozkaz FFFF0 F0 LOCK (przedrostek następnego rozkazu) FFFF1 BC MOV SP,#1000H FFFF2 00 młodszy FFFF3 10 starszy bajt danej wpisywanej do SP FFFF4 FB EI (odblokowanie przerwań) FFFF5 9C PUSHF (zapisz na stosie rejestr statusowy) FFFF6 9D POPF (odczytaj ze stosu rejestr statusowy) FFFF7 BA MOV DX,#C84AH FFFF8 4A młodszy FFFF9 C8 starszy bajt zapisywany do DX FFFFA EF OUTW FFFFB EA JMP (skok bezwzględny poza segment) FFFFC 00 młodszy bajt przesunięcia FFFFD 04 starszy bajt ładowane do IP FFFFE 00 młodszy bajt segmentu FFFFF 00 starszy bajt ładowane do CS Procesor akceptuje Ŝądanie zawieszenia HOLD po kaŝdym cyklu magistrali (dokładniej po kaŝdym cyklu magistrali µp. 8086 dlatego nie akceptuje HOLD w trakcie przesyłania 16- bitowego słowa). Jeśli chcemy ochronić dany rozkaz to umieszczamy przed nim przedrostek LOCK. Ma to znaczenie, gdy magistralę moŝe przejąć inny µp., a dotyczy instrukcji modyfikacji argumentu w pamięci gwarantując wyłączność modyfikacji dla tylko jednego µp. Tutaj przedrostek LOCK przed rozkazem MOV SP wyłącznie w celach demonstracyjnych. W trakcie cykli chronionego rozkazu aktywowane jest wyjście LOCK (dioda na czołówce). PoniewaŜ LOCK chroni tylko pojedynczy rozkaz więc dla sekwencji LOCK rozkaz 1 * LOCK rozkaz 2 będzie moŝliwe zawieszenie w miejscu *. Z tych samych powodów, gdy rozpoczniemy pracę po wyzerowaniu z nastawionym na konsoli Ŝądaniem HOLD, to µp. odda magistralę jeszcze przed wykonaniem pierwszego rozkazu (tu: MOV SP). Pierwszym rozkazem jest załadowanie wskaźnika stosu SP. Jest to oczywiście przesunięcie, które naleŝy odnieść do zawartości rejestru segmentowego stosu SS. PoniewaŜ po wyzerowaniu SS=0 więc pierwsze 16- bitowe słowo zapisywane będzie na stosie pod lokacjami 00FFE i )FFF. Stos będzie rozbudowywał się od ostatniej lokacji wgłąb dysponowanego obszaru pamięci RAM. Procesor rozpoczyna pracę od załadowania SP, aby w przypadku akceptacji przerwania, zapisać 6- bajtową informację do lokacji obsadzonych przez pamięć RAM. Przerwania maskowalne odblokowuje instrukcja EI. Po jej wykonaniu zapali się dioda INTE na CPU. Przerwania niemaskowalne µp. przyjmuje zawsze. Oba przerwania są akceptowane po zakończeniu aktualnie wykonywanej instrukcji. Dlatego teŝ przerwanie NMI (niemaskowalne) zostanie zaakceptowane po rozkazie MOV SP (z przedrostkiem). Oczywiście dla prawidłowej obsługi przerwań konieczna jest obecność właściwych wektorów, w tabeli wektorów przerwań i procedur obsługi rozpoczynających się od adresów zawartych w tych wektorach. Instrukcja PUSHF i POPF zostały umieszczone w celu zaobserwowania stanu początkowego obu bajtów rejestru statusowego (po odblokowaniu przerwań). Rozkaz POPF nie jest do tego konieczny, ale został wstawiony w celu przywrócenia poprzedniej wartości rejestru SP. 6
W celu obserwacji operacji w 64kB przestrzeni we-wy umieszczono instrukcję OUTW (rozmiar słowa, port wyjścia adresowany przez rejestr DX uprzednio zapisany). Zapisuje ona stan początkowy obu bajtów akumulatora (AL. i AH) pod lokacjami (DX) i (DX+1). Mimo określenia 16- bitowego rozmiaru µp. 8086 przy operacjach we-wy operuje zawsze bajtami korzystając wyłącznie z bitów 0-7 szyny danych (dla 8088 nie ma innej moŝliwości). Nastawione rozkazy kończy instrukcja skoku bezwarunkowego, poza segmentowego. W przeciwieństwie do skoków wewnątrz segmentowych (tzw. bliskich), gdzie stosuje się adresację względną w stosunku do bieŝącego stanu IP (za KO 1 bądź 2 bajty przesunięcia w kodzie U2), rozkaz skoku dalekiego (poza segment) ustala bezpośrednio nowe wartości dla rejestrów IP oraz CS (4 bajty za KO). Przekrokuj pierwsze 16- bajtów programu: Zapisz stan magistrali danych w kolejnych krokach programu, oraz stan linii LOCK. segment INT E syg. ster. adres dana syg. LOCK uwagi CS 0 FETCH * FFFF0 µp. ignoruje Ŝądanie HOLD, takŝe w cyklu CS 0 FETCH FFFF1 FFFF4 kiedy do kolejki pobierany jest CS 0 FETCH FFFF2 rozkaz EI, a instrukcja MOV SP jest CS 0 FETCH FFFF3 wykonywana wewnętrznie CS 0 FETCH FFFF4 CS 0 FETCH FFFF5 CS 1 FETCH FFFF6 dopiero teraz µp. zakończył wewnątrz rozkaz EI i ustawił INTE SS 1 MEMW 00FFE dopiero teraz µp. zapisuje rejestr SS 1 MEMW 00FFF statusowy na stos tj. rozkaz spod adresu FFFF5 w cyklach pobrania FETCH jest równieŝ aktywny sygnał MEMR Zwróć uwagę na opóźnienie wykonania instrukcji PUSH. Zapisz stan rejestru znaczników- F i zamień na postać bitową. niewykorzystane V D I T S Z x AC x P x C Widać stąd, Ŝe przerwania są dopuszczone (I=1), praca krokowa wyłączona (T=0). Znaczenie pozostałych bitów: V nadmiar D kierunek S znak Z zerowość AC przeniesienie pomocnicze P. parzystość C przeniesienie 7
Przekrokuj dalszą część programu i podobnie zapisz stan magistrali danych. segment INTE syg. ster adres dana syg. LOCK Uwagi CS 1 FETCH FFFF7 0 SS 1 MEMR 00FFE 0 SS 1 MEMR 00FFF 0 CS 1 FETCH FFFF8 0 CS 1 FETCH FFFFA 0 CS 1 FETCH FFFFB 0 CS 1 IOW 0C84A 0 CS 1 IOW 0C84B 0 CS 1 FETCH FFFFC 0 CS 1 FETCH FFFFD 0 CS 1 FETCH FFFFE 0 CS 1 FETCH FFFFF 0 CS 1 FETCH 00000 0 dopiero teraz następuje odczyt stosu tj. wykonanie instrukcji spod FFFF6 Rozkaz JMP nie został jeszcze pobrany do końca, więc kolejka zostaje uzupełniona jeszcze wg starych wartości CS i IP. CS F F F F IP + 0 0 1 0 ------------------------------------ 0 0 0 0 0 (przeniesienie jest pomijane) Po dokończeniu pobierania instrukcji JMP µp załaduje nowe wartości do CS i IP. CS 0 0 0 0 IP + 0 4 0 0 ------------------------------------ 0 0 4 0 0 i od tego adresu, po uniewaŝnieniu aktualnej zawartości, będzie ładowana kolejka. segment INTE syg. ster. adres dane syg. LOCK uwagi CS 1 FETCH 00400 XX 0 NaleŜy zwrócić uwagę, Ŝe w przypadku krokowania co cykl magistrali kolejka jest zawsze pusta, bo szybkość µp. jest nieporównywalnie większa od szybkości ręcznego dozowania bajtów do kolejki. Zamknięta pętla programowa Korzystając z konsolki wpisz do pamięci następujący program Lista rozkazów uŝywanych w ćwiczeniu znajduje się w tabeli 1.1.: F0400H F0401H F0402H F0403H F0404H NOP NOP NOP NOP NOP 8
F0405H NOP F0406H NOP F0407H NOP F0408H JMP F0400H Wybierz skok względny SJMP i zakoduj odpowiednio przesunięcie ( skok do samego siebie to przesunięcie FEH, do bajtu poprzedniego FDH itd. )a obu kierunkach, np. 2 bajty za skok to przesunięcie 00H. Zanotuj program w postaci hexadecymalnej. Korzystając z konsoli wprowadź program do pamięci od adresu 00400. ZauwaŜ, Ŝe µp. po pobraniu całego rozkazu JMP pobiera jeszcze następny bajt do kolejki, a dopiero potem wykonuje skok. Działanie rozkazu WAIT Pod adresem F0402H zamiast NOP a wpisz rozkaz WAIT (#9BH, przycisk TEST na czołówce wciśnięty). µp. po zdekodowaniu tego rozkazu zatrzymuje się i czeka na impuls wejściowej linii TEST. ZauwaŜ, Ŝe mimo pobrania rozkazu WAIT, µp zatrzyma się dopiero po całkowitym zapełnieniu kolejki, a po zwolnieniu przycisku TEST (proszę go wcisnąć ponownie) wykona rozkazy NOP z kolejki i zacznie się wykonywanie następnych rozkazów. Działanie rozkazu HALT Pod adresem F0402H zamiast rozkazu WAIT wpisz rozkaz HALT- oczekiwanie na przerwanie (#F4H). ZauwaŜ, Ŝe µp po zdekodowaniu tego rozkazu zatrzymuje się i nie zapełnia kolejki wytłumacz i zapisz dlaczego. Sprawdź, Ŝe w stanie HALT µp natychmiast potwierdza zwolnienie magistrali sygnałem HLDA (jeŝeli wcześniej był aktywny sygnał HOLD). Efektywne wyjście ze stanu zatrzymania (oprócz oczywiście podania sygnału RESET) jest moŝliwe tylko dzięki przerwaniu. Obsługa przerwania maskowalnego Wciśnij przycisk INT(14) na module symulatora przerwań. W odpowiedzi µp wykona dwa cykle potwierdzenia przerwania (aktywna linia INTA). Pierwszy cykl słuŝy tylko do synchronizacji układów zarządzających przerwaniami (np. kontrolera przerwań 8259), natomiast w drugim cyklu µp ma otrzymać od urządzenia przerywającego numer wektora obsługi przerwań (00 do FFH). Numer wskazuje 4-ro bitowe pole w zerowym kilobajcie pamięci. PoniewaŜ symulator nie ma wbudowanych mechanizmów wektoryzacji, więc w obu cyklach INTA µp. odbierze FFH (trzeci stan szyny BUS). Odpowiada to ostatniemu wektorowi przerwań o adresie początkowym 03FCH (FFh*04h). W w/w wektorze umieść adres 00500H. 003FCH 003FDH 003FEH 003FFH młodszy bajt offsetu starszy bajt offsetu młodszy bajt CS starszy bajt CS 9
Zawartość poszczególnych komórek pamięci wektora przerwań dobierz tak, aby po zsumowaniu otrzymać Ŝądany adres fizyczny 00500H (nie zachowuj zerowej wartości segmentu CS), zanotuj te wartości. MSB LSB CS 0 W to miejsce µp wpisze cztery bity=0 offset MSB LSB 0 0 5 0 0 Adres fizyczny Od adresu 00500H wpisz następujący program obsługi przerwania: NOP, NOP, PUSHF, POPF, NOP, NOP, IRET (kody instrukcji w tabeli 1.1.). Ponadto pod adresem 00402H ustaw z powrotem rozkaz NOP. Prześledź wyjście i powrót z przerwania (INT jest aktywne poziomem naleŝy po zaakceptowaniu wycofać go). ZauwaŜ, Ŝe podczas cykli INTA świeci LOCK cykli tych nie moŝna rozerwać bezpośrednim dostępem do pamięci µp. na stos składa 6 bajtów. Zapisz te bajty. słowo statusowe CS IP Uporządkuj bajty składane na stos i zapisz w postaci 16 bitowych słów. słowo statusowe CS IP Przekrokuj podprogram obsługi przerwania. Zanotuj stan rejestru flagowego składanego na stosie i ściąganego ze stosu po rozkazach PUSH i POP. Porównaj ze stanem F złoŝonym na stos przed wykonywaniem procedury. Praca krokowa Programowa praca krokowa jest włączana przez ustawienie bitu T w rejestrze F. Bit T jest 8- mym bitem rejestru znaczników (najmłodszym bitem starszego bajtu). Nie ma moŝliwości bezpośredniej modyfikacji rejestru F. Aby ustawić Ŝądany bit T, naleŝy dokonać tzw. wymiany przez stos, z uŝyciem np. akumulatora AX. Wykorzystaj odpowiednie instrukcje z tabeli 1.1. i zapisz w postaci heksadecymalnej poniŝszy program. działanie Mnemonik Adres HEX Ustawienie bitu T 00400 00401 10
Skok względny pod adres 00400 00402 00403 NOP 00404 NOP 00405 NOP 00406 NOP 00407 SJMP 00408 00409 Praca krokowa to przerwanie o numerze 1, a więc wektor obsługi pracy krokowej stanowią komórki: adres 00004 00005 00006 00007 dana Zapisz w tych komórkach adres procedury obsługi przerwania 00700h (zanotuj) Od adresu 700 napisz pseudoprocedurę obsługi pracy krokowej NOP, NOP, PUSHF, POPF, NOP, NOP, IRET. UŜywając konsoli prześledź działanie µp. ZauwaŜ i zanotuj jakie wartości bitów I, T są we wnętrzu µp w czasie procedur śledzenia (widać je podczas wykonania pary instrukcji PUSHF, POPF w trakcie wykonywania procedury). Przesłania blokowe Zrealizuj przesłanie blokowe dziesięciu (0Ah) bajtów danych z pamięci od adresu 00500h pod adres 00600h. Przesłanie blokowe poprzedź przedrostkiem LOCK. Przed rozkazem przesłania blokowego naleŝy: a. Załadować adres źródłowy do rejestrów DS. oraz SI*, b. Załadować adres docelowy do rejestrów ES oraz DI*, c. Załadować ilość bajtów do przesłania do rejestru CX, Następnie: d. Przedrostek LOCK, e. Przedrostek REP, f. Rozkaz przesłania blokowego. *procesor nie posiada rozkazów umoŝliwiających zapisanie danej natychmiastowej do rejestrów indeksowych. Zapis taki jest moŝliwy via akumulator AX. Dla uproszczenia zawartość obu rejestrów segmentowych wykorzystywanych w przesłaniu moŝna wyzerować. Zapisz powyŝszy program w postaci symbolicznej i heksadecymalnej. Mnemonik Adres HEX 00400 11
00401 00402 00403 00404 00405 00406 00407 00408 00409 0040A 0040B 0040C 0040D 0040E 0040F 00410 00411 00412 Wpisz program do pamięci systemu. Po wpisaniu programu w trakcie krokowania przesłania spróbuj zrealizować Ŝądanie oddania magistrali przez procesor konsoli sterującej (przycisk HOLD konsoli). Po kilku krokach wycofaj sygnał HOLD. Zgłoś przerwanie przyciskiem nr 14 na symulatorze przerwań a następnie po powrocie procesora z obsługi przerwania ponownie zaŝądaj zwolnienia magistrali przyciskiem HOLD. ZauwaŜ iŝ tym razem procesor odda magistralę, dzieje się tak dlatego Ŝe podczas składania na stos adresu powrotu z przerwania procesor zapamiętuje tylko jeden przedrostek. Tabela 1.1. Rozkazy uŝyteczne przy realizacji programu Mnemonik Bajt 1 Bajt 2 Bajt 3 IRET CF LOCK F0 MOV AX,n m B8 m n MOV DS,AX 8E D8 MOV ES,AX 8E Co MOV SI,n m BE m n MOV DI,n m BF m n MOV CX,n m C9 m n MOVSB A4 NOP 90 OR AX,n m 0D m n PUSH AX 50 PUSH F 9C POP AX 58 POP F 9D REP F3 SJMP d EB d-przesunięcie 12
(U2) 13