Architektura Systemów Komputerowych - Instrukcja do laboratorium nr 1 i 2
Autor: Mariusz Wiśniewski
-
Architektura mikroprocesora 8086 i pochodne
Poniżej został przedstawiony schemat blokowy mikroprocesora 8086. Funkcje mikroprocesora są wykonywane przez
dwa główne układy: jednostkę łączności z magistralą (BIU) oraz jednostkę wykonawczą (EU). Obie jednostki
współpracują ze sobą, jednakże większość operacji wykonują oddzielnie (asynchronicznie). W jednostce EU znajduje się
16-bitowa jednostka ALU, która aktualizuje stan znaczników stanu i sterujących. Jednostka ALU ma do dyspozycji
rejestry ogólnego przeznaczenia oraz operuje argumentami rozkazów. Wszystkie rejestry oraz przesyłane przez EU
dane są 16-bitowe.
Obecnie jądro mikroprocesora 8086 stanowi niewielką część nowoczesnych mikroprocesorów. Jednakże lista instrukcji
oraz sposoby ich działania nie zostały znacząco zmienione. W nowszych typach mikroprocesorów zostało wprowadzone
32-bitowe słowo maszynowe, a co za tym idzie zostały wprowadzone rejestry o takim rozmiarze, oraz odpowiednie
tryby adresowania i zarządzania pamięcią.
-
Program uruchomieniowy - obsługa
Celem laboratorium Architektury Systemów Komputerowych jest pokazanie funkcjonalności architektury systemu
komputerowego poprzez sprawdzanie sposobu działania instrukcji oraz testowanie szybkości działania programów
ilustrujących sposób działania mikroprocesora. Do tego celu zostanie wykorzystany OllyDbg 1.05, który umożliwia
pracę krokową programów oraz pozwala na wprowadzanie instrukcji procesora. Debbuger należy uruchomić przez
wykonanie polecenia C:\ASK\OLLYDBG.EXE. Następnie należy wybrać opcję menu File|Open
i wskazać plik ASK.EXE. Następnie należy kliknąć myszą na przycisk Open.
Na ekranie pojawi się następujące okno:
Okno Debbugera składa się z czterech podokien. Pierwsze podokno (licząc od strony lewej) zawiera istrukcje programu.
Następne podokno zawiera zawartości rejestrów mikroprocesora. Podokna znajdujące się w drugim wierszu zawierają
odpowiednio zawartość segmentu pamięci (identyfikowane przez rejestry: CS, DS, ES, FS, GS, SS) oraz zawartość
segmentu stosu (identyfikowany przez tylko rejestr SS). Pomiędzy poszczególnymi podoknami można poruszać się przy
pomocy klawisza TAB. Zaraz po uruchomieniu w podoknie programu znajdzie się następująca linia: mov eax, liczba,
gdzie liczba jest adresem danych programu.
Wprowadzanie instrukcji oraz innych danych
Debbuger umożliwa wprowadzanie kodów programu oraz modyfikację danych, w segmentach pamięci, modyfikację
rejestrów oraz stosu. W celu wprowadzania instrukcji lub modyfikacji zawartości innych elementów należy
umieścić kursor we właściwym oknie i rozpocząć wprowadzanie danych:
W powyższym przykładzie jest wprowadzana instrukcja mov eax, 100. Naciśnięcie klawisza
enter spowoduje wprowadzenie instrukcji do pamięci. Podobnie można wprowadzać dane, wartości
rejestrów i znaczników oraz zmieniać zawartość stosu. Należy tu zaznaczyć, że wprowadzane liczby domyślnie
są traktowane jako liczby szesnastkowe.
Wykonywanie instrukcji i testowanie szybkości działania poszczególnych instrukcji
Po wprowadzeniu instrukcji możliwe jest wykonanie poszczególnych instrukcji. W tym celu należy naciskać klawisz
F8. Wykonana zostanie instrukcja wskazana przez kursor Debbugera. Możliwe jest także wykonanie większego
fragmentu programu bez przerwania programu po każdej instrukcji. W tym celu należy przejść kursorem
(linia pozioma w kolorze szarym) do wybranego miejsca i nacisnąć klawisz F4. Program zostanie przerwany
w momencie osiągnięcia punktu, w którym znajdował się kursor. Możliwe jest także zdefiniowanie pułapki
(przez naciśnięcie klawisza F2) w miejscu kursora, a następnie naciśnięcie klawisza F9, co spowoduje wykonanie
programu do momentu napotkania pułapki. Pułapkę likwiduje się przez ponowne naciśnięci F2, gdy kursor znajduje
się w miejscu pułapki.
Szybkość działania programu (lub jednej instrukcji) można określić przez wstawienie do kodu programu instrukcji
rdtsc, która odczytuje specjalny rejestr mikroprocesora, którego zawartość zwiększa się z każdym
taktem zegara systemowego procesora. Po wykonaniu powyższej instrukcji w rejestrach procesora EDX i EAX zostanie
umieszczona aktualna wartość licznika cykli (EDX część starsza).
-
Ćwiczenia
-
Należy wprowadzić następujące instrukcje (od adresu poczatkowego):
mov eax, 100
mov eax, 200
mov ebx, 100
mov ecx, 123
jmp 00401000
Następnie należy wykonać program przez naciskanie klawisza F8. Wyniki działania należy umieścić w sprawozdaniu.
-
Należy wprowadzić następujące instrukcje (od adresu poczatkowego):
mov eax, 100
mov ebx, eax
mov ecx, ebx
mov edx, ecx
jmp 00401000
Następnie należy wykonać program przez naciskanie klawisza F8. Wyniki działania należy umieścić w sprawozdaniu.
-
Należy wprowadzić następujące instrukcje (od adresu poczatkowego):
mov esi, 100
mov edi, 200
jmp 00401000
Następnie należy wykonać program przez naciskanie klawisza F8. Wyniki działania należy umieścić w sprawozdaniu.
-
Należy wprowadzić następujące instrukcje (od adresu poczatkowego):
rdtsc
mov ds:[00403000], eax
mov ds:[00403004], edx
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
mov eax, 100
rdtsc
sub eax, ds:[00403000]
sbb edx, ds:[00403004]
jmp 00401000
Następnie należy przesunąć kursor na pozycję instrukcji jmp 00401000 i ustawić tam pułapkę
naciskając klawisz F2. Następnie należy wykonać program kilkakrotnie przez naciskanie klawisza F9. W komórkach
pamięci o adresach ds:[00403000] i ds:[00403004] zostały zapisana wartość licznika
instrukcji sprzed wykonania ciągu instrukcji mov eax, 100, którą należy odjąć od zawartości
rejestrów EDX i EAX (ma to miejsce w przykładzie). Uzyskany wynik będzie oznaczał ilość cykli w jakich zostały
wykonane powyższe 10 instrukcji mov eax, 100. Wyniki działania należy umieścić w sprawozdaniu.
Zadania do samodzielnego wykonania
-
Sprawdzić czas wykonania przesłania danej z rejestru do pamięci RAM dla rejestrów 32-bitowego (EAX, EBX, ECX
i EDX). Wyniki poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z rejestru do pamięci RAM dla rejestrów 16-bitowego (AX, BX, CX i DX).
Wyniki poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z rejestru do pamięci RAM dla rejestrów 8-bitowego (AL, BL, CL i DL).
Wyniki poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z pamięci RAM do rejestru 32-bitowego (EAX, EBX, ECX i EDX).
Wyniki poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z pamięci RAM do rejestru 16-bitowego (AX, BX, CX i DX).
Wyniki poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z pamięci RAM do rejestru 8-bitowego (AL, BL, CL i DL).
Wyniki poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z rejestru do rejestru 32-bitowego (EAX, EBX, ECX i EDX). Wyniki
poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z rejestru do rejestru 16-bitowego (AX, BX, CX i DX). Wyniki
poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania przesłania danej z rejestru do rejestru 8-bitowego (AL, BL, CL i DL). Wyniki
poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania sekwencji naprzemiennej dla instrukcji przesłania danej do rejestru, następnie
rejestru do pamięci i pamięci do rejestru dla rejestrów 32-bitowych (EAX, EBX, ECX i EDX). Wyniki
poszczególnych rejestrów należy porównać.
-
Sprawdzić czas wykonania sekwencji naprzemiennej dla instrukcji przesłania danej do rejestru, następnie
rejestru do pamięci i pamięci do rejestru dla rejestrów 16-bitowych (AX, BX, CX i DX). Wyniki poszczególnych
rejestrów należy porównać.
-
Sprawdzić czas wykonania sekwencji naprzemiennej dla instrukcji przesłania danej do rejestru, następnie rejestru
do pamięci i pamięci do rejestru dla rejestrów 8-bitowych (AL, BL, CL i DL). Wyniki poszczególnych rejestrów
należy porównać.