Procesor pobiera z pamięci i wykonuje rozkazy sterujące całą jego pracą. Jest praktycznie za wszystko odpowiedzialny. Na rynku jest wiele typów procesorów. Różnią się one szybkością i komendami. Ponieważ wszystkie procesory 8086 i w górę powinny być ze sobą kompatybilne , będziemy zajmować się w głównej mierze 8086.
Praca procesora polega na pobieraniu z pamięci rozkazów wraz z danymi i wykonywaniu ich. Dane i rozkazy niczym między sobą w pamięci się nie różnią. Ta sama liczba może być traktowana jako kod rozkazu lub wartość innego. Procesor steruje również pracą urządzeń zewnętrznych np. klawiatura, karta graficzna, muzyczna itp. Do współpracy z nimi służą tzw. porty wejścia/wyjścia. W celu szybszego operowania danymi każdy procesor został wyposażony w kilka rejestrów, czyli bajtów pamięci.
Procesory 8086 (i nowsze, jednak te posiadają jeszcze inne rejestry) posiada 14 rejestrów 16-bitowych. Osiem pierwszych z nich to tzw. rejestry ogólnego przeznaczenia. Cztery pierwsze można traktować zarówno jako rejestry 16-bitowe bądź jako złożenie dwóch rejestrów 8-bitowych, i tak:
AX (ang. Accumulator)
|
Rejestr ten jest wykorzystywany głównie do operacji arytmetycznych i logicznych. Można go traktować jako rejestr 16-bitowy bądź jako dwa rejestry 8-bitowe: AH i AL. AH jest to bardziej znacząca część rejestru AX, AL jest to mniej znacząca część. Bardziej znacząca oznacza, że są to drugie 8-bitów rejestru AX, a mniej znacząca to pierwsze 8-bitów. Trzeba tylko dodać, że kolejność bitów jest następująca: 7,6,5,4,3,2,1,0. Np. AX=234FH, więc AH=23H, a AL=4FH. Ponieważ jest 16-bitowy może pomieścić liczby z zakresu 0-1111111111111111b czyli od 0-65535. Większej wartości w tym rejestrze umieścić się nie da.
|
BX (ang. Base Registers)
|
Rejestr bazowy, głównie wykorzystywany przy adresowaniu pamięci. Rejestr ten również dzieli się na dwa rejestru ośmio bitowe: BH i BL.
|
CX (ang. Counter Registers)
|
Rejestr ten jest bardzo często wykorzystywany jako licznik, np. przy instrukcji LOOP. Dzieli się na dwa rejestry 8-bitowe CH i CL.
|
DX (ang. Data Register)
|
Rejestr danych, wykorzystywany przy operacjach mnożenia i dzielenia, a także do wysyłania i odbierania danych z portów. Dzieli się na DH i DL.
|
Wszystkie te rejestry, o ile instrukcja wykonywana zezwala mogą być wykorzystywane do innych celów. Trzeba zauważyć ,że jeśli zmieniamy zawartość rejestru 16-bitowego np. AX zmieniają się również wartości rejestrów 8-bitowych składowych tego rejestru, w tym wypadku AH i AL, oraz odwrotnie, zmiana AH czy AL zmienia wartość rejestru AX.
SI (ang. Source Index)
|
Rejestr indeksujący pamięć oraz wskazujący obszar z którego przesyła się dane. Zazwyczaj występuje w połączeniu z DS tworząc adres logiczny DS:SI
|
DI (ang. Destination Index)
|
Rejestr indeksujący pamięć oraz wskazujący obszar, do którego przesyłamy dane. Występuje z ES, tworząc adres logiczny ES:DI
|
SP (ang. Stack Pointer)
|
Wskaźnik stosu.
|
BP (ang. Base Pointer)
|
Rejestr używany do adresowania pamięci.
|
Jest jeszcze jeden rejestr, ale jest on nie osiągalny bezpośrednio przez programistę. Jest to IP (Instruction Pointer) wskaźnik instrukcji. Zawiera on adres aktualnie wykonywanej instrukcji i może być modyfikowany przez rozkazy sterujące pracą programu.
Podczas wykonywania operacji korzystających z pamięci , rejestry ogólnego przeznaczenia zawierają tylko offset tych adresów, czyli przesunięcie w danym segmencie. Te przekazywane są za pomocą innych rejestrów, tzw. rejestrów segmentowych. Są to:
CS (ang. Code Segment)
|
Rejestr zawierający segment aktualnie wykonywanego rozkazu. Razem z IP tworzy pełny adres logiczny CS:IP kolejnej instrukcji do wykonania.
|
DS (ang. Data Segment)
|
Rejestr zawierający segment z danymi.
|
ES (ang. Extra Segment)
|
Rejestr zawierający segment np. przy operacjach przesyłania łańcuchów.
|
SS (ang. Stack Segment)
|
Rejestr zawierający segment stosu.
|
FS - dowolne zastosowanie
|
GS - dowolne zastosowanie
|
Rejestry te są używane niejawnie w zależności od kontekstu, np. skok do komórki o adresie 0 tak naprawdę jest to skok do komórki o adresie CS:0, a odczyt komórki 0, to odczyt komórki o adresie DS:0. Można w niektórych sytuacjach podawać samemu segment i offset.
By zapisać jakąś wartość do któregoś z tych rejestrów, należy posłużyć się rejestrem ogólnego przeznaczenia np. by ustawić segment danych na 5 należy napisać:
MOV AX,5
MOV DS,AX
lub posłużyć się stosem, np:
PUSH 5
POP DS
Rejestry segmentowe istnieją ze względu na podział pamięci komputera właśnie na segmenty 64KB-owe (w rzeczywistym trybie pracy procesora). Z tego też względu każda komórka pamięci opisana jest dwoma wartościami: numer segmentu i przesunięcie (offset) względem początku tego segmentu. Procesor oblicza adres rzeczywisty mnożąc numer segmentu przez 16 i dodając przesunięcie.
Zapis np.: CS:IP to adres logiczny. Adres rzeczywisty, to: 16*CS+IP Ostatnim rejestrem jest tzw. rejestr znaczników zwany też rejestrem flagowym. Do tego rejestru również nie można odwoływać się bezpośrednio. Do tego celu używa się specjalnych instrukcji. Dla programisty rejestr ten to 9 pojedynczych bitów informujących o stanie procesora, np. by porównać dwie wartości (wykonać polecene Pascal'owe IF) używa się instrukcji CMP. Jednak wynik tej instrukcji tzn. czy np. dana liczba jest większa od innej uzyskujemy właśnie za pomocą odpowiednio ustawionych znaczników. Instrukcja CMP ustawia je w odpowiedni sposób. Część z tych znaczników można ustawiać, a część tylko odczytywać. Położenie i znaczenie poszczególnych bitów jest następujące:
O (ang. Overlow Flag)
|
Znacznik nadmiaru, zostaje ustawiony przy wystąpieniu nadmiaru w operacjach arytmetycznych, czyli np. przy przekroczeniu dopuszczalnego zakresu wyniku operacji.
|
D (ang. Direction Flag)
|
Znacznik kierunku, określa czy dane będą przesyłane w kolejności adresów rosnących, czy malejących. Jeśli jest równy 0, to SI i DI będą zwiększane, w przeciwnym wypadku będą zmniejszane.
|
I (ang. Interrupt Flag)
|
Znacznik zezwolenia na przerwanie, określa czy przerwanie sprzętowe ma być wykonane natychmiast po zgłoszeniu, czy dopiero po zakończeniu wykonywania programu.
|
T (ang. Trap Flag)
|
Znacznik pracy krokowej. Określa, czy po każdej wykonanej instrukcji procesora wykonywane jest przerwanie pracy krokowej.
|
S (ang. Sign Flag)
|
Znacznik znaku. Zawiera znak wyniku ostatnio wykonanej operacji arytmetycznej.Jest to kopia najstarszego bitu wyniku.
|
Z (ang. Zero Flag)
|
Znacznik zera.Zostaje ustawiony,jeśli wynikiem ostatniej operacji arytmetycznej był wynik zero.
|
A (ang. Auxiliary Carry Flag)
|
Znacznik przeniesienia połówkowego. Zostaje ustawiony, gdy mamy do czynienia z przeniesieniem z bitu 3 na bit 4 lub pożyczką z bitu 4 na 3
|
P (ang. Parity Flag)
|
Znacznik parzystości.Flaga ta zostaje ustawiona gdy w bitowej wartości wyniku wystąpiła parzysta ilość jedynek(lub zer)
|
C (ang. Carry Flag)
|
Znacznik przeniesienia.
|
Wszystkie powyższe rejestry, są dostępne od procesora 8086. Jednak od 386 dostępne są jeszcze inne rejestry:
EAX,EBX, ECX, EDX, EBP, ESI, EDI
Są to 32 bitowymi rozszerzeniami rejestrów AX, BX itd. Zależność jest taka sama jak AX i AL. Teraz AX jest mniej znaczącym słowem (2 bajty) rejestru EAX. Bardziej znaczącego słowa nie ma. Rejestry te są często wykorzystywane w operacjach matematycznych ze względu na dużą pojemność.
Mamy jeszcze rozszerzony rejestr EFLAGS (32-bitowy rejestr flag), EIP, oraz nowe rejestry segmentowe GS i FS
Rejestry mają z góry ustalone sugerowane przeznaczenie. Dla tego dobrze jest się przyzwyczaić do używania ich zgodnie z założeniem. Np. rejestr ECX jast sugerowany jako licznik. Nie musimy go do tego używać, bo można np. liczyć sobie ilość kółek w pętli w innym rejestrze lub zmiennej, ale z ECX współpracuje przeciez instrukcja LOOP, a także inne tak jak REP. Wiem, nie zawsze mamy akurat wolny ten rejestr, którego akurat byśmy potrzebowali, lecz starajcie się trzymać następującej konwencji: