Architektura Systemów Komputerowych Architektura x86 Architektura Systemów Komputerowych mgr inż. Michał Misiak
Wstęp x86 – termin odwołujący się do zbioru instrukcji procesora o jednym z największych sukcesów komercyjnych Wykorzystywany w procesorach AMD, Intel, VIA Kompatybilny ze starymi 16-bitowymi procesorami Intel Historycznie zostało dodanych wiele nowych instrukcji w taki sposób, że procesory są zgodne z poprzednikami Termin stał się popularny po wdrożeniu do sprzedaży procesora 32-bit 80386 (należy wyróżnić procesory x86-16 i x86-64) Architektura popularna w rozwiązaniach PC, Notebook oraz serwerach Architektura wspierana jest przez szereg systemów operacyjnych: MS-DOS, Windows, Linux, BSD, Solaris
Historia 1978 – Intel 8086 1982 – Intel 80286 8MHz, 0,029mln tranzystorów Układ 16 bitowy (w tańszej wersji posiadał 8 bitową szynę danych 8088) 1982 – Intel 80286 12,5MHz, 0,134 mln Druga generacja układów x86, słowo 16 bitowe z zwiększoną 24 bitową szyną adresową, nowe rozkazy oraz tryby pracy Adresowanie umożliwiało obsługę 16 MB RAM oraz 1GB pamięci wirtualnej
Historia (2) 1985 – 80386 1989 – i486 1993 – Pentium 20 MHz, 0,275 mln Procesor 32 bity, poszerzone rejestry wewnętrzne, szyna danych oraz adresowa Posiada MMU, nowe rozkazy, tryb wirtualny, obsługa do 4GB pamięci RAM 1989 – i486 25 MHz, 1,2mln rozszerzono o kilka nowych instrukcji, zwiększona wydajność jednostki stałoprzecinkowej. Posiada pamięć cache L1 1993 – Pentium 66 MHz, 3,1mln Powiększono pamięć cache L1, dodano jednostkę przewidywania skoków, zewnętrzna magistrala danych do 64 bitów, szyna adresowa 36 bity, możliwość realizacji dwóch rozkazów jednocześnie. Procesor superskalarny.
Historia (3) 1995 - Pentium PRO (nieformalnie arch. i686) 200 MHz, 5,5 mln tranzystorów Dedykowany do serwerów i wydajnych stacji roboczych, układ posiada wiele cech architektury RISC pod względem mikroarchitektury, 6 potoków, podstawa dla procesorów Pentium II i Pentium III, osobno wbudowana pamięć cache L2 1995 – Pentium MMX 233 MHz, 4,5 mln tranzystorów Ulepszony Pentium z rozkazami MMX
Historia (4) 1997 – Pentium II/III 2000 – Pentium IV 266MHz, 7mln Technologie 3D Now, pamięć cache L3 2000 – Pentium IV 1,5GHz, 42 mln Nowy projekt procesora pod kątem maksymalnego wykorzystania potkowości pozwalające osiągać duże częstotliwości zegara 2006 – Intel Core, Intel Core 2 Ok. 3GHz, 320 mln tranzystorów Niskonapięciowy, wolniejszy zegar, wielordzeniowy
Potrzebne skróty IA-32 – nazwa 32 bitowej architektury x86 IA-64 – model programowy dla procesora do serwerów z możliwością wykonywania kodu 32 bitowego EM64T (Extended Memory 64 Technology) – nazwa implementacji technologii AMD x86-64 AMD64 – x86-64/x64 – architektura 64 firmy AMD. Procesory Athlon 64/FX/X2, Sempron, Turion, Opteron
Podstawowe cechy architektury x86 Instrukcje zmiennej długości Architektura CISC z uwzględnieniem kompatybilności wstecz Słowo w porządku little-endian Adresy rejestrów w większości przypadków 3 bitowe
Obecne implementacje Zastosowanie dodatkowych etapów dekodowania instrukcji w celu podziału na mniejsze części Zastosowanie architektur: superskalarnej out-of-order execution Rozszerzenia: 3DNow MMX SSE
MMX MultiMedia eXtensions lub Matrix Math eXtensions Zestaw 57 instrukcji SIMD (Single Instruction, Multiple Data z taksonomii Flynna) Stosowany w sytuacji, gdy przetwarzane są duże ilości danych przez jeden algorytm (np. obróbka dźwięku, obróbka obrazu)
3DNow! Rozszerzenie arch. x86 stworzone przez AMD Zwiększa wydajność obliczeń zmiennoprzecinkowych wykorzystywane do odtwarzania grafiki trójwymiarowej i multimediów Wspiera i rozszerza możliwości akceleratorów graficznych w początkowych etapach przetwarzania grafiki Zawiera 21 instrukcji SIMD
SSE SSE - Streaming SIMD Extensions Nazwa zestawu instrukcji wprowadzonych w procesora Pentium III Pozwala na wykonywanie działań zmiennoprzecinkowych na 4 elementowych wektorach liczb pojedynczej precyzji SSE wprowadza zmiany w arch. procesora: Dodano 8 rejestrów XMM w wersji 32 bity, a w wersjach 64 bity jest dostępnych jeszcze kolejne 8
Out-of-order execution Nowe podejście przy przetwarzaniu w procesorze: Pobranie instrukcji Zbuforowanie instrukcji w kolejce Instrukcja oczekuje w kolejce do momentu kiedy argument wejściowy staje się dostępny. Instrukcja może opuścić kolejkę wcześniej przed starszymi instrukcjami Instrukcja jest przekazywana do właściwego bloku funkcjonalnego i wykonywana Rezultaty są kolejkowane Tylko w momencie, gdy wszystkie rezultaty zostaną zwrócone do rejestru wówczas cały wynik jest zapisywany do rejestru Korzyści: Wypełnianie pustych slotów czasowych (procesor wykonuje te instrukcje, do których są dane, później kolejkuje wynik) Wzrost efektywności przetwarzania w sytuacji różnicy częstotliwości pamięci i procesora, procesor nie musi oczekiwać na napływające dane Stosowanie w procesorach: Pentium PRO (’95), IBM/Motorola PowerPC (‘92), Fujitsu/HAL SPARC64 (’95)
Arch. Superskalarna Możliwość ukończenia kilku instrukcji na raz w jednym cyklu pracy procesora Procesor posiada zwielokrotnione jednostki wykonawcze umożliwiające obliczenia równoległe (np. ALU, jednostki zmiennopozycyjne) Możliwość realizacji instrukcji w arch. Superskalarnej zależy od tego, czy dana instrukcja nie potrzebuje argumentów źródłowych z poprzedniej Konieczna odpowiednia optymalizacja rozmieszczenia instrukcji, w celu unikania zależności danych Pierwszym procesorem był Pentium z 2 jednostkami wykonawczymi (jedna wykonywała instrukcje proste).
Mechanizm segmentacji pamięci w x68 Pamięć dzielna jest na segmenty Adresacja przestrzeni dwuwymiarowa: adres logiczny – widziany przez aplikacje, procesy adres fizyczny (pojawiający się na wyprowadzeniach procesora) Do adresacji (adres liniowy) wykorzystywane są rejestry segmentowe: adres początkowy aplikacji oraz przesunięcie w stosunku do początku aplikacji Zaletą segmentacji jest ochrona innych części pamięci przed zapisem bądź odczytem przez inną aplikację Wady: ograniczone segmenty, konieczność dzielenia aplikacji pod wymiary segmentów
Translacja adresu logicznego na liniowy Źródło: http://www.microsoft.com/poland/technet/article/art0092_01.mspx
Zestaw rejestrów Rejestry jednostki stałopozycyjnej 8 32-bitowych rejestrów uniwersalnych mogących przechowywać dane 16 i 32 bitowe Dane 16 bitowe przechowywane w mniej znaczących połówkach Możliwość przechowywania danych 8 bitowych w pierwszych 4 rejestrach Nazwy rejestrów pochodzą od nazw specjalizowanych rejestrów ze starszych procesorów w arch. X86 16bit Nazwy rejestrów 32 bitowych powstały w wyniku poprzedzenia nazwy rejestru 16 bitowego literą E
Lista rejestrów Nazwa: 8bit, 8bit, 16bit, 32bit Akumulator: AH, AL, AX, EAX Licznik: CH, CL, CX, ECX Rejestr adresowy: BH, BL, BX, EBX Wskaźnik stosu: SP, ESP Wskaźnik ramki: BP, EBP Rejestry adresowe: SI i DI, ESI i EDI Licznik instrukcji: IP, EIP Rejestr stanu: FLAGS, EFLAGS Rejestry selektorów: Selektor kodu CS Selektor stosu SS Główny selektor DS Dodatkowe selektory danych ES, FS, GS
Funkcje rejestrów Rejestr EAX (accumulator) – akumulator dla operacji mnożenia i dzielenia, operacji arytmetycznych na liczbach w kodzie BCD oraz instrukcji iteracyjnych Rejestr ECX (counter) – licznik pętli, licznik iteracji w instrukcjach z pętlą, licznik pozycji w operacjach przesunięć i rotacji bitowych Rejestr EDX (data) – rozszerzenie akumulatora w operacjach mnożenia i dzielenia Rejestr ESP (stack pointer) – wskaźnikiem stosu Rejestr EBP (base pointer) – wskaźnikiem ramki Rejestr ESI (source index) – wskaźnik źródła dla instrukcji iteracyjnych Rejestr EDI (destination Index) – wskaźnik przeznaczenia dla instrukcji iteracyjnych Wskaźnik instrukcji EIP (Instruction Pointer) – rejestr licznika instrukcji
Rejestr stanu (EFLAGS) Zawiera bity znaczników i stanów aplikacji, informacje systemowe (dostępne do odczytu lub niedostępne dla użytkownika) Z poziomu aplikacji dostępne są bity: CF – znacznik przeniesienia PF – znacznik parzystości AF – znacznik przeniesienia połówkowego ZF – znacznik zera SF – znak liczby w kodzie U2 OF – znacznik nadmiaru przy operacjach na liczbach w kodzie U2 DF – bit sterujący działaniem instrukcji iteracyjnych ID – bit sygnalizujący dostępność instrukcji CPUID. CPUID dostępny w procesorach posiadających instrukcję CPUID
Rejestry selektorów Przechowują identyfikatory segmentów Niewykorzystywane w środowiskach 32 bitowych, ograniczone wykorzystanie przez system operacyjny (używano w 16 bitowyc) Rejestry są inicjalizowane przez OS przy starcie programu. Program użytkowy ma dostęp do rejestrów jednak nie powinien ich modyfikować W x86 jest 6 rejestrów w tym 3 pomocnicze
Rejestry jednostki zmiennopozycyjnej W układach do 80486 jednostka pozycyjna była realizowana w zew. układzie (np. dla procesora 8086 był to układ 8087) Jednostka zm. poz. (x87) zawiera 8 rejestrów 80 bitowych zorganizowanych w postaci stosu rejestrów Wierzchołek stosu traktowany jako domyślny argument Rejestry nie mają nazw są indeksowane za pomocą cyfr Rejestry przechowują dane w formacie zmiennopozycyjnym podobnym do IEEE dla double jednak wydłużonym do 64 bitów
Rejestry 3DNow!/MMX Jednostka wektorowa 3DNOW operuje na słowa 64 bitowych posiada 8 rejestrów Rejestry są nałożone logicznie na rejestry zmiennopozycyjne można wykorzystywać tylko jeden, przełączenie z x87 na MMX następuje po wywołaniu instrukcji MMX Przywrócenie stanu rejestrów sprzed wywołania MMX następuje po wywołaniu EMMS i FEMMS Przewiduje się następujące sposoby interpretacji: Pojedyncza dana całkowitoliczbowa o długości 64 bity 2xdana całkowitoliczbowa o długości 32 bit 4xdana całkowitoliczbowa o długości 16 bit 8xdana całkowitoliczbowa o długości 8 bit 2xdana zmiennopozycyjna w 3DNOW po 32 bity
Rejestry jednostki wektorowej SSE Jednostka SSE zbudowana jest z 8 rejestrów 128 bitowych Jednostka SSE może przechowywać dane w następujących formatach: 16 danych całkowitoliczbowych 8 bitowych 8 danych całkowitoliczbowych 16 bitowych 4 dane całkowitoliczbowe 32 bitowe 2 dane całkowitoliczbowe 64 bitowe 4 dane zmiennopozycyjne 32 bitowe 2 dane zmiennopozycyjne 64 bitowe
Realizacja operacji warunkowych Realizacja zgodnie z modelem operacji warunkowych ze znacznikami typowy dla architektur CISC Znaczniki ustawiane przez instrukcje arytmetyczne i logiczne nie są natomiast ustawiane przez instrukcje przesłań
Tryby pracy Tryb rzeczywisty Tryb chroniony Procesor pracuje jak procesor 8086 Brak ochrony pamięci przed użyciem przez inny proces oraz brak obsługi wielozadaniowości w oparciu o tryb rzeczywisty pracowały programy w DOS w latach 80 i 90 Dostępna pamięć do 1 MB Adres logiczny złożony z 2 x liczba 16 bitowa (nr segmentu oraz przemieszczenia) Tryb chroniony Tryb wprowadzony w mikroprocesorze 80286 Możliwość adresacji w obszarze większym niż 1 MB Wprowadza udogodnienia dla wielozadaniowości: sprzętowa ochrona pamięci (MMU), wsparcie dla przełączenia kontekstu procesora
MMU MMU – Memory Management Unit Zestaw układ realizujących dostęp do pamięci fizycznej żądanej przez CPU Zadania układu: Translacja pamięci wirtualnej do pamięci fizycznej Ochrona pamięci Obsługa pamięci podręcznej Zarządzanie szynami danych
MMU (2) Układy MMU dzielą przestrzeń logiczną na strony o rozmiarze 2N Młodsze N bitów odpowiada Tłumaczenie adresów logicznych na fizyczne realizowane przy pomocy asocjacyjnej pamięci podręcznej TLB (Translation Lookaside Buffer) W przypadku braku przypisania wykorzystywane są wolniejsze sprzętowe mechanizmy procesora przeszukujące struktury danych znajdujących się w pamięci Struktura nosi nazwę Page Table Adres fizyczny ustalany po dodaniu przesunięcia (offset) do numeru strony, a wpisy nazywają się Page Table Entries. W x86 wymagane jest 4kB do przechowywania katalogu stron http://pl.wikipedia.org/wiki/MMU
Wykonywanie programów na IA-32 IA-32 posiada rozbudowany zestaw instrukcji (kilkaset) rozbudowywany wraz z wprowadzaniem nowych technologii MMX, SSE, 3DNow! Grupy instrukcji: Instrukcje przesyłania danych Instrukcje kontroli przepływu (porównania skoki, pętle) Instrukcje arytmetyczne Instrukcje operacji logicznych Operacje bitowe Instrukcje identyfikowane na podstawie binarnego kodu maszynowego. W celu ułatwienia programowania zastąpione memonikami
Kodowanie instrukcji Kodowaniem instrukcji zajmuje się kompilator Rozkazy zakodowane w postaci ciągów 0 i 1 Rozkazy zmiennej długości od 1 do kilkunastu bajtów Kod instrukcji: identyfikator rozkazu + położenie argumentów w pamięci Wynik zapisywany jest w miejscu pierwszego operandu
Budowa rozkazu Prefiks instrukcji (o) Kod operacji LOCK – zapewnia wyłączność dostępu do pamięci dla danej instrukcji Prefiks powtarzanie – używany na blokach danych Prefiks chwilowej zmiany segmentu Prefiks zmiany rozmiaru argumentu oraz rozmiaru adresu Kod operacji Bit wskazujący w którym argumencie zapisać wynik Bit oznaczający rozmiar argumentów Baj modR/M dla instrukcji posiadających argumenty w pamięci bądź rejestrach, wykorzystywany do określenia położenia argumentów Bajt SIB – określa dodatkowe parametry modyfikacji adresowych, m.in.. współczynnik skali pozwalający wygodnie operować na tablicach Pole przesunięcia – podaje odległość danych w stosunku do początku Dane stałe – zawiera bezpośrednio podaną wartość argumentu
Cykl wykonania rozkazu Pobranie rozkazu z pamięci Dekodowanie rozkazu Obliczenie adresu efektywnego uwzględniającego modyfikacje adresowe w przypadku odwołania do pamięci Obliczenie adresu fizycznego operandu Pobranie argumentu z pamięci Wykonanie rozkazu Zapisanie wyniku Wyznaczenie położenia następnego rozkazu