Architektura Systemów Komputerowych - Instrukcja do laboratorium nr 1 i 2
Autor: Mariusz Wiśniewski


  1. 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ą.

  2. 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).

  3. Ćwiczenia
    1. 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.

    2. 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.

    3. 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.

    4. 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.

  4. Zadania do samodzielnego wykonania

    1. 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ć.
    2. 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ć.
    3. 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ć.
    4. 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ć.
    5. 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ć.
    6. 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ć.
    7. 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ć.
    8. 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ć.
    9. 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ć.
    10. 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ć.
    11. 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ć.
    12. 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ć.