Procesory

Architektura x86

opublikowano przez Marcin Bienkowski w dniu 2012-02-20

architektura x86

Czy zastanawialiście się kiedyś nad tym, jak zbudowane są obecne procesory zgodne z architekturą x86? Dlaczego są one w stanie wykonać jednocześnie kilka operacji, jakie mają bloki wykonawcze, co to jest superskalarność, wielowątkowość i jak są one realizowane? Przyjrzyjmy się zatem, co kryje się pod pojęciem architektury współczesnych procesorów i jaka jest ich konstrukcja.  

Pod pojęciem architektury procesora rozumie się wszystkie najważniejsze z punktu widzenia budowy i funkcjonalności cechy układu, które związane są zarówno z jego modelem programowym, jak i fizyczną budową. Model programowy procesora (ang. Instruction Set Architecture) to zestaw instrukcji procesora oraz innych jego cech (np. liczby i numeracji rejestrów czy sposobu adresowania pamięci) istotnych z punktu widzenia programisty, które są niezależne od ich wewnętrznej realizacji w procesorze.

Z kolei fizyczna budowa układu nazywana też mikroarchitekturą (ang. microarchitecture). To szczegółowa implementacja danego modelu programowego, która związana jest z rzeczywistym wykonywaniem operacji przez procesor. Co ciekawe, operacje te mogą być realizowane w zupełnie odmienny sposób niż wynikałoby to z modelu programowego. Przykładem może być tutaj wykonywanie kilku instrukcji poza kolejnością lub przewidywanie skoków warunkowych, czego nie znajdziemy w modelu programowym.

Mikroarchitekturę procesora przedstawia się jako zbiór diagramów określających poszczególne jego elementy, takie jak bloki funkcjonalne czy jednostki wykonawcze oraz występujące między nimi połączenia. W mikroarchitekturze nie określa się natomiast faktycznej, fizycznej implementacji obwodów logicznych w krzemowej strukturze układu, a więc składających się na nie bramek i wchodzących w ich skład tranzystorów. W tym miejscu warto podkreślić, że procesory realizujące ten sam model programowy mogą w znaczący sposób różnić się od siebie swoją mikroarchitekturą – dobrym przykładem są układy firm AMD i Intel, które są zgodne z programową architekturą x86, ale są całkowicie różnymi układami pod względem swojej mikroarchirektury.

Architektura x86

Zanim zaczniemy przyglądać się mikroarchitekturze współczesnych jednostek centralnych montowanych w pecetach, laptopach czy netbookach warto kilka słów poświęcić najczęściej wykorzystywanej w tej klasie sprzętu architekturze x86.

Sama nazwa architektury x86 odnosi się do modelu programowego procesorów wykorzystanego przez Intela w 1978 roku w 16-bitowej kości Intel 8086. Procesor ten w 1981 roku wykorzystany został przez firmę IBM – a właściwie nieco jego okrojona wersja Intel 8088, w której zmniejszono do 8 bitów szerokość magistrali danych – do skonstruowania pierwszego komputera IBM PC. Popularność jaką zyskały komputery typu PC, a później ich następcy doprowadziła do popularyzacji architektury x86 i jej dalszego rozwoju, który trwa do dzisiaj. Swoją nazwę architektura x86 zawdzięcza zaś kolejnym generacjom układów Intela, wykorzystujących zastosowany w procesorze Intel 8086 model programowy, a które oznaczane były kolejno jako Intel 80286, Intel 80386 oraz Intel i486. Procesor Intel i486 był też ostatnim modelem zawierającym na końcu nazwy cyfry 86. Jego następca, procesor piątej generacji zgodnej z modelem programowym x86, nosił już bowiem nazwę Pentium.

Procesor Intel 8086 z 1978 roku, od którego wzięła początek architektura x86.
Procesor Intel 8086 z 1978 roku, od którego wzięła początek architektura x86

Pierwszy procesor Intel 8086 był typowym przedstawicielem bardzo popularnych w tamtym czasie układów typu CISC (ang. Complex Instruction Set Computing), które przetwarzają złożone, specjalistyczne rozkazy, często w kilku lub kilkunastu cyklach zegara. Takie procesory cechują się mniejszą wydajnością, ale za to są znacznie prostsze w programowaniu i dysponują szeroką gamą trybów adresowania. Z kolei druga grupa procesorów, czyli procesory RISC (ang, Reduced Instruction Set Computing) wyróżniają się tym, że korzystają z minimalnej liczby bardzo szybko wykonujących się rozkazów, które przy odpowiedniej konstrukcji układu mogą być przetwarzane jednocześnie. Jednak pod koniec lat 70. ubiegłego stulecia układy RISC wymagały nie tylko sporego doświadczenia od programisty, ale również bardzo skomplikowanych kompilatorów.

Jak można się domyślić wybór typu wykorzystywanej przez procesor listy rozkazów pomiędzy CISC a RISC (obecnie wykorzystuje się jeszcze m.in. architektury VLIW – Very Long Instruction Word, bazującą na niej architekturę EPIC – Explicitly Parallel Instruction Computing czy MISC – Minimal Instruction Set Computer) w znacznej mierze determinuje samą mikroarchitekturę układu. Procesory CISC są bardziej skomplikowane. W wypadku Intela 8086 konstruktorzy zastosowali dwie współpracujące ze sobą jednocześnie jednostki: moduł wykonawczy EU (Execution Unit) oraz moduł interfejsów BIU (Bus Interface Unit), łączący procesor z magistralą systemową.

W skład modułu wykonawczego weszła 16-bitowa jednostka arytmetyczno-logiczna ALU (Arithmetic Logic Unit), która odpowiada za realizację operacji wykonywanych przez procesor (może ona wykonywać zarówno operacje 8-, jak i 16-bitowe), blok sterowania, blok rejestrów ogólnego przeznaczenia oraz 16-bitowy rejestr znaczników (rejestr flag, ang. flag register), który bezpośrednio podłączony jest do ALU. Flagi zostały podzielone na dwie grupy: kontrolną i arytmetyczną. Flagi arytmetyczne informują o wyniku ostatniej operacji wykonanej przez jednostkę arytmetyczno-logiczną, a flagi kontrolne sterują pracą procesora.

Blok rejestrów ogólnego przeznaczenia składa się z czterech rejestrów 16-bitowych (SP – wskaźnik stosu, BP – wskaźnik bazy, SI – rejestr adresu operandu źródłowego, DI – rejestr adresu przeznaczenia) oraz czterech par rejestrów ośmiobitowych (AH/AL, BH/BL, CH/CL, DH/DL), które są dostępne dla programisty również jako cztery rejestry 16-bitowe (AX – akumulator, BX – baza, CX – licznik, DX - dane). Procesor 8086 dysponował 16-bitową magistralą danych, 20-bitową magistralą adresową, miał do dyspozycji siedem trybów adresowania argumentów w pamięci, a zestaw instrukcji składał się z 91 rozkazów.

Schemat blokowy mikroprocesora Intel 8086.
Schemat blokowy mikroprocesora Intel 8086.

1) Blok rejestrów ogólnego przeznaczenia (rejestry arytmetyczne, indeksowe i wskaźnikowe).
2) Jednostka arytmetyczno-logiczna wraz z rejestrem flag.
3) Blok rejestrów segmentowych wraz z licznikiem rozkazów.
4) Generator adresu fizycznego (20-bitowy sumator).
5) Kolejka rozkazów, 6 komórek pamięci (każda o rozmiarze bajta) zorganizowanych w słowa.
6) Kontroler interfejsu.
7) Układ kontrolny.

Co ważne, ten podstawowy model programowy architektury x86 przetrwał do dzisiaj – został on oczywiście przez lata rozbudowany i zmodyfikowany, ale kompatybilność w dół została zachowana. Dzięki temu nawet dziś na najnowszych układach zgodnych z architekturą x86 można bez problemu uruchomić najstarsze aplikacje pochodzące jeszcze z 1981 roku. Nie umożliwia tego w prosty sposób żadna inna platforma.