Porównywanie zawartości rejestrów i komórek pamięci
jak sprawdzić czy liczba (bez znaku) umieszczona w rejestrze BX jest większa od liczby (bez znaku) umieszczonej w rejestrze CX ?
instrukcje arytmetyczne i logiczne ustawiają bity rejestru znaczników w zależności od wartości wyniku operacji; w operacjach na liczbach bez znaku istotne znaczenie mają bity rejestru znaczników:
CF znacznik przeniesienia, ustawiany w stan 1 w przypadku wystąpienia przeniesienia (przy dodawaniu) lub pożyczki (przy odejmowaniu);
ZF znacznik zera, ustawiany w stan 1, jeśli wynik operacji arytmetycznej lub logicznej jest równy 0 — w przeciwnym razie znacznik ustawiany jest w stan 0;
zbadajmy w jaki sposób zostaną ustawione znaczniki CF i ZF po wykonaniu rozkazu odejmowania,
sub bx, cx
przy założeniu, że wcześniej w rejestrach BX i CX zostały umieszczone liczby bez znaku; czynności tego rozkazu można zapisać symbolicznie (BX) ← (BX) (CX)
rozpatrzymy trzy przypadki:
1. (BX) > (CX) ZF = 0 CF = 0
2. (BX) = (CX) ZF = 1 CF = 0
3. (BX) < (CX) ZF = 0 CF = 1
dla każdego ww. przypadku zawartości znaczników CF i ZF są niejednakowe; zatem poprzez zbadanie stanu znaczników CF i ZF po wykonaniu odejmowania można stwierdzić czy liczby są równe albo która z liczb jest większa ;
z podanych rozważań wyniku, że w celu sprawdzenia czy liczba zawarta w rejestrze BX jest większa od liczby zawartej w rejestrze CX należy odjąć zawartości tych rejestrów i sprawdzić czy po wykonaniu odejmowania oba znaczniki CF i ZF zawierają zera; zauważmy, że ustawienie znaczników CF = 0 i ZF = 0, jest możliwe tylko wówczas gdy (BX) > (CX);
w rozpatrywanym przykładzie odejmowanie zawartości rejestrów zostaje wykonane nie w celu uzyskania różnicy liczb, ale w celu ustawienia znaczników CF i ZF; z tego powodu operację odejmowania wykonuje się za pomocą rozkazu CMP, który działa prawie dokładnie tak samo jak zwykły rozkaz odejmowania SUB — jedyna różnica polega na tym, że rozkaz CMP nigdzie nie wpisuje wyniku odejmowania, ustawia natomiast znaczniki; zatem po wykonaniu rozkazu CMP zawartości rejestrów pozostają niezmienione;
dla wygody programowania konstruktorzy procesora Pentium (i poprzedników) opracowali szereg rozkazów sterujących (skokowych), które testują różne warunki występujące przy porównywaniu liczb, np. przy porównywaniu liczb bez znaku używane są rozkazy:
Mnemonik |
Testowany warunek |
ja |
CF = 0 i ZF = 0 |
jae |
CF = 0 |
je |
ZF = 1 |
jne |
ZF = 0 |
jb |
CF = 1 |
jbe |
CF = 1 lub ZF = 1 |
podane rozkazy występują bezpośrednio za rozkazem CMP; w omawianym przykładzie sprawdzenie czy liczba w rejestrze BX jest większa od liczby w rejestrze CX można wykonać za pomocą poniższych rozkazów (obie liczby są liczbami bez znaku):
cmp bx, cx
ja wieksze
— — — —
— — — —
wieksze:
jeśli (BX) > (CX), to nastąpi skok do rozkazu opatrzonego etykietą wieksze, w przeciwnym razie rozkazy będą wykonywane w naturalnej kolejności;
do porównywania liczb bez znaku i liczb ze znakiem używa się nieco innych instrukcji sterujących
Rodzaj porównywanych liczb |
liczby bez znaku |
liczby ze znakiem |
skocz, gdy większy |
ja (jnbe) |
jg (jnle) |
skocz, gdy mniejszy |
jb (jnae, jc) |
jl (jnge) |
skocz, gdy równe |
je (jz) |
je (jz) |
skocz, gdy nierówne |
jne (jnz) |
jne (jnz) |
skocz, gdy większy lub równy |
jae (jnb, jnc) |
jge (jnl) |
skocz, gdy mniejszy lub równy |
jbe (jna) |
jle (jng) |
w nawiasach podano mnemoniki instrukcji o tych samych kodach — w zależności konkretnego porównania można bardziej odpowiedni mnemonik, np. instrukcję jae używamy do sprawdzania czy pierwszy operand instrukcji cmp (liczby bez znaku) jest większy lub równy od drugiego; jeśli chcemy zbadać pierwszy operand jest niemniejszy od drugiego, to używamy instrukcji jnb — instrukcje jae i jnb są identyczne i są tłumaczone na ten sam kod.
Identyfikacja nadmiaru w operacjach arytmetycznych
w trakcie wykonywania operacji arytmetycznych wynik może przekraczać dopuszczalną wartość, co określane jest jako nadmiar lub przepełnienie;
ponieważ ten sam rozkaz dodawania ADD stosowany jest zarówno dla liczb bez znaku, jak i dla liczb ze znakiem, więc konieczne jest sygnalizowanie nadmiaru za pomocą dwóch znaczników; i tak znacznik CF sygnalizuje nadmiar, jeśli dodawane są liczby bez znaku, a znacznik OF sygnalizuje nadmiar przy dodawaniu liczb ze znakiem;
znaczniki CF i OF używane są także do sygnalizacji nadmiaru przy odejmowaniu (rozkaz SUB) liczb bez znaku i ze znakiem;
w celu bliższego wyjaśnienia problemu nadmiaru przy dodawaniu rozpatrzmy przykład; przyjmijmy, że rejestr BL zawiera liczbę 0011 1001, a rejestr BH liczbę 1111 1111; obie liczby zostają dodane za pomocą rozkazu
ADD BH, BL
w wyniku dodawania uzyskamy wartość
0011 1001 |
1111 1111 |
0011 1000 |
jeśli w trakcie dodawania wystąpił nadmiar, to uzyskany wynik jest błedny; ponieważ nie wiemy czy dodawane liczby są liczbami bez znaku albo liczbami ze znakiem, więc musimy rozpatrzyć dwa przypadki;
przy założeniu, że dodawane liczby są liczbami bez znaku, mamy w istocie dodawanie 57 + 255 = 312; otrzymaliśmy jednak błędny wynik 56; łatwo zauważyć, że przy dodawaniu obu najstarszych bitów występuje przeniesiesie, co oznacza wynik sumowania zajmuje 9 bitów i nie da się zapisać w 8-bitowym rejestrze BH; procesor wpisuje przeniesienie występujące przy dodawaniu na najstarszej pozycji do znacznika CF;
przy założeniu, że dodawane liczby są liczbami ze znakiem w kodzie U2, mamy w dodawanie 57 + (−1) = 56, co stanowi wynik poprawny; w tym przypadku nadmiar sygnalizowany jest za pomocą znacznika OF, do którego wpisywana jest suma modulo dwa przeniesień występujacych przy dodawaniu na najstarszym bicie i poprzednim;
konieczność użycia dwóch znaczników nadmiaru wynika z tego, że procesor „nie wie” czy dodawane liczby są kodowane jako liczby bez znaku czy ze znakiem — informacje takie posiada natomiast autor programu; w tej sytuacji procesor wyznacza zawartości obu znaczników, a autor programu testuje jeden z nich, zależnie od przyjętego sposobu kodowania;
do testowania omawianych znaczników używane są rozkazy podane w tablicy:
Mnemonik |
Testowany warunek |
jc |
CF = 1 |
jnc |
CF = 0 |
jo |
|
jno |
|
nadmiar przy mnożeniu nie występuje, a znaczniki CF i OF używane są do kodowania pewnych własności wyniku mnożenia;
nadmiar przy dzieleniu powoduje wygenerowanie wyjątku procesora (zob. podany dalej opis przerwań i wyjątków); praktycznie oznacza to przekazanie sterowania do systemu operacyjnego i zakończenie wykonywania programu.
Dodawanie liczb wielokrotnej długości
Przykład: dodawanie dwóch liczb 24-bitowych
0011 1010 0000 0111 1011 0010
0010 0000 1100 0010 0101 0011
dodawanie przeprowadzimy za pomocą trzech operacji dodawania 8-bitowego
przedstawione działania wykonuje poniższa sekwencja instrukcji
mov al, 10110010B ; najmłodsza cz. pierwszej liczby
mov ah, 00000111B ; środkowa część pierwszej liczby
mov bh, 00111010B ; najstarsza część pierwszej liczby
mov dl, 01010011B ; najmłodsza część drugiej liczby
mov dh, 11000010B ; środkowa część drugiej liczby
mov ch, 00100000B ; najstarsza część drugiej liczby
add al, dl
adc ah, dh
adc bh, ch
Operacje bitowe
rozkazy AND, TEST, OR, XOR wykonują operacje logiczne na odpowiadających sobie bitach obu operandów — rezultat wpisywany jest do operandu docelowego, i jednocześnie ustawiane są znaczniki ZF, SF, PF (znaczniki CF i OF są zerowane); rozkaz TEST ustawia znaczniki, ale nie wpisuje wyniku;
rozkaz NOT jest jednoargumentowy — następuje zanegowanie wszystkich bitów;
AND |
bitowy iloczyn logiczny |
TEST |
bitowy iloczyn logiczny (bez wpisywania wyniku) |
OR |
bitowa suma logiczna |
XOR |
bitowa suma modulo dwa |
NOT |
negacja bitowa |
poniżej podano przykład ilustrujący działanie rozkazu NOT:
kolejny przykład ilustruje działanie rozkazów sumy logicznej OR, iloczynu logicznego AND i sumy modulo dwa XOR;
rozkaz XOR jest dość często używany do zerowania rejestrów, aczkolwiek jest to raczej nietypowe jego zastosowanie, np.
xor si, si
Operacje na pojedynczych bitach
w mikroprocesorach jednoukładowych, sterujących rozmaitymi urządzeniami, których stan opisywany jest często wartościami binarnymi, np. drzwi otwarte albo zamknięte, zasilanie włączone albo wyłączone, itp., szerokie zastosowanie znajdują rozkazy umożliwiające testowanie i zmiany pojedynczych bitów; rozkazy tej klasy zostały wprowadzone także w procesorze Pentium:
BT |
bit nie ulega zmianie |
BTS |
wpisanie 1 do bitu |
BTR |
wpisanie 0 do bitu |
BTC |
zanegowanie zawartości bitu |
każdy ww. rozkaz ma dwa operandy:
pierwszy określa słowo lub podwójne słowo zawierające modyfikowany bit;
drugi wskazuje numer bitu, na którym ma być wykonana operacja;
podane rozkazy, przed wykonaniem operacji, przepisują zawartość wskazanego bitu do znacznika CF;
przykłady:
btc ax, cx
bt edi, 29
do omawianej klasy można zaliczyć również rozkaz CMC, który powoduje zanegowanie zawartości znacznika CF;
w niektórych urządzeniach każdy bit pewnego rejestru opisuje jakiś element stanu układu — wystąpienie wartości 1 na którymś z bitów oznacza, że w w pracy układu wystąpiły zakłócenia, i trzeba wszystkim zidentyfikować ich przyczynę, czyli określić numer bitu, który zawiera 1; w procesorze Pentium do tego celu można wykorzystać rozkazy przeszukiwania:
BSF |
poszukiwanie bitu jedynkowego (w prawo) |
BSR |
poszukiwanie bitu jedynkowego (w lewo) |
w podanych rozkazach przeglądany jest drugi operand, zaś wynik (numer bitu) wpisywany jest do pierwszego operandu.
Przesunięcia bitowe
w procesorze Pentium zdefiniowane różne rodzaje operacji przesunięcia bitów w rejestrze lub w lokacji pamięci; wyróżnia się przesunięcia w lewo lub w prawo, przesunięcia logiczne i cykliczne (tzw. obroty); dodatkowo zdefiniowano przesunięcie cykliczne (rozkazy RCL i RCR), w którym znacznik CF traktowany jest jako dodatkowy bit przesuwanego rejestru;
SHL (SAL) |
przesunięcie logiczne (arytmetyczne) w lewo |
SHR |
przesunięcie logiczne w prawo |
SAR |
przesunięcie arytmetyczne w prawo |
ROL |
przesunięcie cykliczne w lewo |
ROR |
przesunięcie cykliczne w prawo |
RCL |
przesunięcie cykliczne w lewo przez CF |
RCR |
przesunięcie cykliczne w w prawo przez CF |
poniższy rysunek przedstawia schematycznie przesunięcie cykliczne (obrót) w lewo; bity wychodzące z pozycji 7 kierowane są na pozycję 0; dodatkowo bity wychodzące wprowadzane są także do znacznika CF;
przesunięcia logiczne działają podobnie, ale wity wychodzące nie są zawracane, a bit nr 0 wprowadzane są zera; przesunięcia w prawo działają analogicznie;
rozkazy RCL i RCR traktują znacznik CF jako rozszerzenie przesuwanego rejestru — poniższy rysunek ilustruje przesunięcie cykliczne w prawo przez znacznik CF;
działanie rozkazu RCR DH,1 ilustruje poniższy przykład;
Wyodrębnianie pól bitowych
omawiane wcześniej rozkazy przesunięć i operacji logicznych stosowane są często do wyodrębniania pól bitowych; w podanym niżej przykładzie zadanie polega na wyznaczeniu liczby umieszczonej na bitach 5 ÷ 3 rejestru AH;
Po wykonaniu powyższych instrukcji rejestr AH zawiera analizowaną liczbę 3-bitową zakodowaną w zwykły sposób.
Liczby stało- i zmiennoprzecinkowe
opisy rozkazów arytmetycznych wykonywanych przez procesor podawane są zazwyczaj przy założeniu, że operacje wykonywane są na liczbach całkowitych; nic nie stoi jednak na przeszkodzie, by wykonywać także działania na liczbach ułamkowych i mieszanych — wymaga to przekształcenia algorytmu w taki sposób, by operacje na ułamkach zostały zastąpione przez operacje na liczbach całkowitych; operacje i dodawania i odejmowania nie wymagają żadnych przekształceń, o ile wagi przypisane odpowiadającym sobie bitom obu operandów są jednakowe; przy mnożeniu i dzieleniu trzeba brać pod uwagę położenie umownej kropki rozdzielającej część całkowitą i ułamkową;
przykładowo, można przyjąć format kodowania podany na poniższym rysunku;
podany wyżej sposób kodowania jest kłopotliwy w przypadku, gdy w obliczenie wykonywane jest na liczbach bardzo dużych i bardzo małych, np. obliczenie stałej czasowej obwodu RC:
wartości R i C w postaci binarnej mają postać
R=01000111 10110111 01100000
C=0.00000000 00000000 00000000 00000000 01001100 . . . . .
kodowanie z zadowalającą dokładnością obu tych liczb wymagałoby wprowadzenia 24 bitów dla części całkowitej i 40 bitów dla części ułamkowej, co w konsekwencji wymagałoby zdefiniowania formatu 8-bajtowego; łatwo zauważyć, że reprezentacja binarna wartości 68 pF zawierała by 57 bitów zerowych z lewej strony, a reprezentacja wartości 4.7 M zawierała by 40 bitów zerowych z prawej strony;
z tego względu obliczenia na liczbach niecałkowitych wykonywane są zazwyczaj w arytmetyce zmiennoprzecinkowej (zmiennopozycyjnej); w procesorze Pentium zdefiniowana jest znaczna liczba instrukcji wykonujących działania na liczbach zmiennoprzecinkowych działających w koprocesorze arytmetycznym.
Liczby zmiennoprzecinkowe
liczby zmiennoprzecinkowe, nazywane też zmiennopozycyjnymi, kodowane są w postaci pary liczb określanych jako mantysa i wykładnik;
w przypadku ogólnym wartość liczby zmiennoprzecinkowej (różnej od zera) określa wyrażenie:
podane wyrażenie w realizacjach komputerowych ma zwykle nieco inną postać;
pole wykładnika można interpretować jako liczbę pozycji, o którą trzeba przesunąć w lewo lub w prawo umowną kropkę rozdzielającą część całkowitą i ułamkową mantysy;
zazwyczaj wprowadza się warunek normalizacji mantysy (dla liczb 0)
liczba 0 traktowana jest jako wartość specjalna i reprezentowana jest przez kod zawierający same zera w polu wykładnika i mantysy;
obliczenia wykonywane na komputerach różnych typów powinny dawać jednakowe rezultaty; w komputerach starszych typów, ze względu na różne formaty liczb zmiennoprzecinkowych i inne reguły zaokrąglania, postulat ten nie zawsze był spełniony;
z tych powodów przyjęto normę IEEE 754, która została opracowana z myślą aby ułatwić przenoszenie programów z jednego procesora do drugiego — określa ona specyficzne metody i procedury służące temu, aby arytmetyka zmiennoprzecinkowa dawała jednolite i przewidywalne wyniki, niezależnie od platformy sprzętowej; norma ta jest stosowana praktycznie we wszystkich we wszystkich współczesnych procesorach i koprocesorach arytmetycznych;
norma IEEE 754 określa też standardowe formaty liczb zmiennoprzecinkowych; podstawowym formatem liczb jest format 64-bitowy; pokazano, że uzyskiwanie dokładnych wyników 64-bitowych wymaga wykonywania niektórych obliczeń na liczbach 80-bitowych.
Formaty liczb zmiennoprzecinkowych
koprocesor arytmetyczny wykonuje działania na liczbach zmiennoprzecinkowych 80-bitowych w formacie pośrednim (nazywanym też chwilowym, ang. temporary real, extended precision);
liczba 0 kodowana jest jako tzw. wartość wyjątkowa (zob. dalszy opis): pole mantysy i pole wykładnika zawiera same zera;
oprócz formatu 80-bitowego pośredniego koprocesor akceptuje także inne formaty zmiennoprzecinkowe, całkowite i BCD; obliczenia wykonywane są najczęściej na liczbach zmiennoprzecinkowych w formacie 64-bitowym, które określane są jako liczby zmiennoprzecinkowe długie (ang. double precision); stosowany jest także format 32-bitowy — liczby zapisane w tym formacie określane są jako liczby zmiennoprzecinkowe krótkie (ang. single precision);
warunek normalizacji mantysy wymaga, by jej wartość (dla liczb 0) zawierała się w przedziale (2, 1> lub <1, 2); oznacza to, że bit cześci całkowitej mantysy (dla liczb 0) będzie zawsze zawierał 1 — zatem można pominąć bit części całkowitej mantysy, zwiększając o 1 liczbę bitów cześci ułamkowej; takie kodowanie stosowane jest w formatach 64- i 32-bitowych — mówimy wówczas, że część całkowita mantysy występuje w postaci niejawnej;
w celu uniknięcia konieczności wprowadzenia znaku wykładnika stosuje się przesunięcie wartości wykładnika o:
16383 = 3FFFH dla formatu 80-bitowego, czyli
1023 = 3FFH dla formatu 64-bitowego, czyli
127 = 7FH dla formatu 32-bitowego, czyli
ponadto koprocesor akceptuje 3 formaty liczb całkowitych (16-bitowy, 32-bitowy i 64-bitowy) oraz 80-bitowy format BCD;
obliczenia wewnątrz koprocesora prowadzone są zawsze w formacie zmiennoprzecinkowym 80-bitowym;
kompilatory języka C kodują wartości typu double jako liczby zmiennoprzecinkowe 64-bitowe, a wartości float jako liczby zmiennoprzecinkowe 32-bitowe;
stosowane formaty liczb zmiennoprzecinkowych pozwalają na kodowanie liczb bardzo dużych i bardzo małych, co jest szczególnie ważne w obliczeniach technicznych; przykładowo w formacie 32-bitowym można kodować liczby o wartościach do 3.371038, a w formacie 64-bitowym nawet do 1.6710308; z drugiej strony możliwe jest kodowanie liczb bardzo małych, np. w formacie 64-bitowym można zakodować z zadowalającą dokładnością (ok. 14 cyfr dziesiętnych) liczby bliskie 2.2310308; takie same zakresy dotyczą również liczb ujemnych.
Przykład kodowania liczby zmiennoprzecinkowej
Kodowanie liczby 12.25 w formacie 32-bitowym
Liczbę 12.25 przedstawiamy w postaci iloczynu
. Wykładnik potęgi k musi być tak dobrany, by spełniony był warunek normalizacji mantysy
, czyli
Łatwo zauważyć, że warunek normalizacji jest spełniony, gdy k = 3. Zatem
Ponieważ część całkowita mantysy nie jest kodowana, więc w polu mantysy zostanie wpisana liczba
, zaś w polu wykładnika (po przesunięciu o 127) liczba
. Ostatecznie otrzymamy
Zasady wykonywania obliczeń przez koprocesor arytmetyczny
koprocesor arytmetyczny stanowi odrębny procesor, współdziałający z procesorem głównym, i w przypadku Pentium znajdujący się w tej samej obudowie; wcześniejsze wersje koprocesorów (387, 287, 8087) konstruowane były w postaci oddzielnych układów scalonych;
liczby, na których wykonywane są obliczenia, składowane są w 8 rejestrach 80-bitowych tworzących stos;
Rejestry stosu |
|
|
Pola rejestru stanu |
|
R7 |
|
|
|
R6 |
|
|
|
R5 |
|
|
|
R4 |
|
|
|
R3 |
|
|
|
R2 |
|
|
|
R1 |
|
|
|
R0 |
|
|
(rejestry 80-bitowe) |
|
|
pola 2-bitowe |
z każdym rejestrem związane jest 2-bitowe pole stanu rejestru (nazywane także polem znaczeń); wszystkie pola stanu tworzą 16-bitowy rejestr zwany rejestrem stanu stosu koprocesora; interpretacja pola stanu jest następująca:
0 - rejestr zawiera liczbę różną od zera,
1 - rejestr zawiera zero,
2 - rejestr zawiera błędny rezultat,
3 - rejestr jest pusty;
rozkazy koprocesora adresują rejestry stosu nie bezpośrednio, ale względem wierzchołka stosu; w kodzie asemblerowym rejestr znajdujący się na wierzchołku stosu oznaczany jest ST(0) lub ST, a dalsze ST(1), ST(2),..., ST(7); ze względu na specyficzny sposób adresowania koprocesor arytmetyczny zaliczany jest do procesorów o architekturze stosowej;
mechanizmy stosu rejestrów koprocesora są analogiczne do mechanizmów stosu w procesorze (m.in. stos rośnie w kierunku malejących numerów rejestrów);
lista rozkazów koprocesora arytmetycznego zawiera rozkazy wykonujace działania na liczbach zmiennoprzecinkowych, w tym rozkazy przesłania, działania arytmetyczne, obliczanie pierwiastka kwadratowego, funkcji trygonometrycznych (sin, cos, tg, arc tg), wykładniczych i logarytmicznych;
przykładowo, do obliczenia wartości funkcji tangens używa się rozkazu FPTAN, który w wyniku podaje dwie liczby — ich iloraz stanowi wartośc funkcji; w celu obliczenia tg bezpośrednio po rozkazie FPTAN należy wykonać rozkaz FDIV (bez operandów).
|
|
FPTAN tg = p/q |
|
|
ST(0) |
/31.047 |
|
q 1 |
ST(0) |
ST(1) |
x |
|
p 1.73 |
ST(1) |
|
|
|
x |
ST(2) |
|
|
|
|
|
Przykład: obliczanie wartości wyrażenia
wynik = (aa bb) cc
dane SEGMENT
aa dd 7.0
bb dd 6.0
cc dd 3.0
wynik dd ?
dane ENDS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov ax,SEG dane
mov ds,ax
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
finit ; inicjalizacja koprocesora
fld cc ; ładowanie zmiennej cc
fld bb ; ładowanie zmiennej bb
fld aa ; ładowanie zmiennej aa
aktualna sytuacja |
|
|
na stosie |
cc |
ST(2) |
koprocesora |
bb |
ST(1) |
|
aa |
ST |
|
|
|
; mnożenie ST(1) ST(1) ST(0)
fmulp ST(1), ST(0)
; wynik mnożenia zostanie wpisany do ST(1), ale ponieważ
; mnemonik instrukcji zawiera literę "p" (pop), więc po wykonaniu
; operacji liczba znajdująca się na wierzchołku stosu zostanie
; usunięta — zatem wynik mnożenia będzie znajdował się
; na wierzchołku stosu
; podaną instrukcję można też zapisać krócej: fmul
; (bez operandów)
aktualna sytuacja |
|
|
na stosie |
cc |
ST(1) |
koprocesora |
aa bb |
ST |
|
|
|
|
|
|
fxch ST(1) ; zamiana ST(0) z ST(1)
aktualna sytuacja |
|
|
na stosie |
aa bb |
ST(1) |
koprocesora |
cc |
ST |
|
|
|
|
|
|
; dzielenie ST(1) ST(1) ST(0)
fdivp ST(1), ST(0)
; wynik dzielenia zostanie wpisany do ST(1), ale ponieważ
; mnemonik instrukcji zawiera literę "p" (pop), więc po wykonaniu
; operacji liczba znajdująca się na wierzchołku stosu zostanie
; usunięta — zatem wynik dzielenia będzie znajdował się
; na wierzchołku stosu
; podaną instrukcję można też zapisać krócej: fdiv
; (bez operandów)
aktualna sytuacja |
|
|
na stosie |
(aa bb) / cc |
ST |
koprocesora |
|
|
|
|
|
|
|
|
fst wynik ; po tej instrukcji stos nie zmienia się
Rejestry pomocnicze koprocesora
aktualny stan koprocesora można określić poprzez odczytanie zawartości 16-bitowego rejestru stanu koprocesora; rejestr ten zawiera różne pola informujące o przebiegu obliczeń, wystąpieniu specjalnych warunków, określa położenie wierzchołka stosu i inne informacje;
z kolei rejestr sterujący zawiera pola, które modyfikują działanie koprocesora; zawartość tego rejestru zmienia się wyłącznie wskutek jawnego załadowania go przez program; poprzez ustawienie odpowiednich bitów w tym rejestrze można określić sposób zaokrąglania, sposób reagowania koprocesora na pewne zdarzenia w trakcie obliczeń (np. dzielenie przez zero) i inne;
Wartości specjalne w koprocesorze arytmetycznym
złożone obliczenia numeryczne trwają czasami wiele godzin czy nawet dni;
wystąpienie nadmiaru lub niedomiaru nie powinno powodować załamania programu (praktyka wskazuje, że w złożonych obliczeniach wyniki pośrednie z nadmiarem czy niedomiarem często mają niewielki wpływ na wynik końcowy);
spośród dopuszczalnych wartości liczb wyłączono niektóre i nadano im znaczenie specjalne — takie liczby określane są terminem wartości specjalne; wartości specjalne mogą być argumentami obliczeń tak jak zwykłe liczby; jeśli jeden z argumentów jest wartością specjalną, to wynik jest też wartością specjalną - w wielu przypadkach obserwuje się propagację wartości specjalnych.
w koprocesorze arytmetycznym przyjęto, że wszystkie liczby, których pole wykładnika zawiera same zera lub same jedynki traktowane są jako wartości specjalne;
w zależności od ustawienia bitów w rejestrze sterującym koprocesora, wystąpienie wartości specjalnej może powodować przerwanie (wyjątek koprocesora), albo też obliczenia mogą być kontynuowane; przykładowo, wartość rezystancji R dla podanego układu można wyznaczyć z zależności
zamaskowanie wyjątku "dzielenie przez zero" pozwala na poprawne obliczenie rezystancji R podanego układu, także w przypadku, gdy wartość rezystancji R1 lub R2 lub R3 wynosi 0.
Kodowanie tekstów
Przykładowe kody ASCII różnych znaków
a |
0110 0001 |
61H |
b |
0110 0010 |
62H |
c |
0110 0011 |
63H |
d |
0110 0100 |
64H |
e |
0110 0101 |
65H |
f |
0110 0110 |
66H |
— — — — — |
|
|
y |
0111 1001 |
79H |
z |
0111 1010 |
7AH |
A |
0100 0001 |
41H |
B |
0100 0010 |
42H |
C |
0100 0011 |
43H |
D |
0100 0100 |
44H |
E |
0100 0101 |
45H |
F |
0100 0110 |
46H |
— — — — — — |
|
|
Y |
0101 1001 |
59H |
Z |
0101 1010 |
5AH |
! |
0010 0001 |
21H |
" |
0010 0010 |
22H |
# |
0010 0011 |
23H |
$ |
0010 0100 |
24H |
— — — — — |
|
|
{ |
0111 1011 |
7BH |
| |
0111 1100 |
7CH |
0 |
0011 0000 |
30H |
1 |
0011 0001 |
31H |
2 |
0011 0010 |
32H |
3 |
0011 0011 |
33H |
— — — — — — |
|
|
8 |
0011 1000 |
38H |
9 |
0011 1001 |
39H |
Znak |
a |
ą |
A |
Ą |
kody znaków podano w zapisie szesnastkowym |
||||
Latin 2 |
61 |
A5 |
41 |
A4 |
Windows 1250 |
61 |
B9 |
41 |
A5 |
ISO 8859-2 |
61 |
B1 |
41 |
A1 |
Mazovia |
61 |
86 |
41 |
8F |
Unicode (mniejsze niżej) |
61 00 |
05 01 |
41 00 |
04 01 |
Unicode (mniejsze wyżej) |
00 61 |
01 05 |
00 41 |
01 04 |
UTF-8 |
61 |
C4 85 |
41 |
C4 84 |
Zasady komunikacji z urządzeniami zewnętrznymi
rozmaite rodzaje urządzeń zewnętrznych komputera wymagają doprowadzenia określonych sygnałów, specyficznych dla danego urządzenia, np. monitor ekranowy wymaga przekazywania, obok informacji o treści wyświetlanego obrazu, także impulsów synchronizujących, które sygnalizują rozpoczęcie kreślenia nowej linii i nowego obrazu;
w tej sytuacji niezbędne jest zainstalowanie układów pośredniczących, które dopasowują standardy sygnałowe procesora i płyty głównej do specyficznych wymagań poszczególnych urządzeń; takie układy pośredniczące nazywane są często układami wejścia/wyjścia; zwykle układy wejścia/wyjścia umieszczane są na kartach rozszerzeniowych lub na płycie głównej komputera;
w ten sposób sterowanie pracą urządzeń jest realizowane za pomocą podzespołów tworzących układy wejścia/wyjścia; podzespoły te umożliwiają testowanie stanu (gotowości) urządzenia, wysyłanie poleceń do urządzenia oraz wysyłanie i przyjmowanie danych; od strony procesora ww. komunikacja odbywa się zazwyczaj poprzez zapis i odczyt rejestrów zainstalowanych w układach wejścia/wyjścia;
stosowane są dwie metody dostępu do zawartości rejestrów układów wejścia/wyjścia:
rejestry udostępniane są jako zwykłe komórki pamięci w przestrzeni adresowej pamięci — mówimy wówczas o współadresowalnych układach wejścia/wyjścia;
rejestry urządzenia dostępne są w odrębnej przestrzeni adresowej zwanej przestrzenią adresową wejścia-wyjścia lub przestrzenią adresową portów; takie rozwiązanie określane jest czasami jako izolowane wejście-wyjście;
stosując pierwszą metodę można odczytywać i zapisywać rejestry urządzenia tak samo jak zwykłe komórki pamięci, np. za pomocą instrukcji MOV; w komputerach PC metoda ta stosowana w odniesieniu do pamięci ekranu;
stosując drugą metodę konieczne jest zdefiniowanie odrębnych instrukcji przesyłania działających w przestrzeni adresowej portów: w procesorze Pentium rolę te pełnią instrukcje IN i OUT (i ich rozszerzenia), np.
in al, 60H — przesłanie zawartości portu 60H do rejestru AL (w PC: odczyt numeru naciśniętego klawisza);
out 64H, al — przesłanie zawartości rejestru AL do portu 64H.
Współadresowalne układy wejścia/wyjścia
typowym przykładem wykorzystania techniki układów współadresowalnych jest pamięć ekranu w komputerach PC; w trybie tekstowym sterownika VGA (lub podobnego) znaki wyświetlane na ekranie stanowią odwzorowanie zawartości obszaru pamięci od adresu fizycznego B8000H; pamięć ta należy do przestrzeni adresowej procesora, ale zainstalowana jest na karcie sterownika VGA;
każdy znak wyświetlany na ekranie jest opisywany przez dwa bajty w pamięci ekranu: bajt o adresie parzystym zawiera kod ASCII znaku, natomiast następny bajt zawiera opis sposobu wyświetlania, nazywany atrybutem znaku;
kolejne bajty omawianego obszaru odwzorowywane są w znaki na ekranie począwszy od pierwszego wiersza od lewej do prawej, potem drugiego wiersza, itd. tak jak przy czytaniu zwykłego tekstu;
Pamięć ekranu w trybie graficznym
współczesne sterowniki (karty) graficzne oferują zazwyczaj wiele trybów wyświetlania, różniących się rozdzielczością, liczbą kolorów i innymi parametrami — wszystkie sterowniki realizują nadal funkcje zwykłego sterownika VGA; sterownik VGA oferuje między innymi dość prosty tryb graficzny oznaczony numerem 13H, w którym raster ma wymiary 320 * 200 pikseli, przy 256 kolorach;
wprowadzenie sterownika w tryb 13H najłatwiej przeprowadzić za pomocą funkcji BIOSu:
mov ah, 0 ; funkcja nr 0 ustawia tryb sterownika wg AL
mov al, 13H ; nr trybu
int 10H
w trybie 13H pamięć ekranu, zawierająca 64000 bajtów (320 * 200), umieszczona jest począwszy od adresu fizycznego A0000H; kolejne bajty w tym obszarze opisują kolory pikseli wg standardowej palety VGA (paletę można zmienić), np. 10 oznacza kolor jasnozielony; podany niżej fragment programu powoduje wyświetlenie jasnozielonej linii pionowej w środku ekranu;
mov ax, 0A000H ; adres pamięci ekranu
mov es, ax
mov cx, 200 ; liczba linii na ekranie
mov bx, 160 ; adres początkowy
ptl_lin: mov byte PTR es:[bx], 10 ; kolor jasnozielony
add bx, 320
loop ptl_lin
za pomocą wywołania INT 10H / AH=0 / AL=3 można powrócić do trybu tekstowego.
Przestrzeń adresowa portów
do zapisu i odczytu danych w przestrzeni adresowej portów stosuje się instrukcje IN i OUT oraz ich rozszerzenia; jeśli numer portu nie przekracza FFH (zajmuje nie więcej niż 8 bitów), to stanowi argument bezpośredni instrukcji IN lub OUT; dla większych numerów konieczne jest pośrednictwo rejestru DX, np.
mov dx, 378H
in al, dx
Wybrane porty układów płyty głównej i układów wejścia/wyjścia
Adres |
Nazwa układu |
000H - 01FH |
Sterownik DMA nr 1 |
020H - 03FH |
Sterownik przerwań 8259A (master) |
040H - 05FH |
Generatory programowalne |
060H - 06FH |
Sterownik klawiatury |
070H - 07FH |
Zegar czasu rzeczywistego |
|
|
Przykład zmiany palety w trybie graficznym
w omawianym wcześniej trybie graficznym 13H (VGA) używana jest standardowa paleta, w której kod 10 oznacza kolor jasnozielony; podany niżej fragment programu dokonuje zmiany palety, w taki sposób, że kod 10 oznaczać będzie kolor żółty;
zmiany palety dokonywana jest poprzez wpisanie kodu koloru do portu 3C8H, a następnie przesłanie składowych: R (czerwony), G (zielony), B (niebieski) do portu 3C9H; poszczególne składowe mogą przyjmować wartości z przedziału <0, 63>;
mov dx, 3C8H
mov al, 10 ; kod koloru
out dx, al
mov dx, 3C9H
mov al, 63 ; składowa czerwona (R)
out dx, al
mov al, 63 ; składowa zielona (G)
out dx, al
mov al, 0 ; składowa niebieska (B)
out dx, al
Przykład sterowania poprzez port 2FCH
w komputerach PC przesyłanie danych z/do urządzeń nie wymagających dużych prędkości przesyłania realizowane jest poprzez łącze szeregowe w standardzie RS232C; dostępne są zazwyczaj dwa takie łącza oznaczane symbolami COM1 i COM2; niekiedy instalowane są także łącza COM3 i COM4; sterowanie pracą tych łączy realizują układy UART (np. 16550A), dostępne poprzez porty o numerach:
COM1 3F8H 3FFH
COM2 2F8H 2FFH
COM3 3E8H 3EFH
COM4 2E8H 2EFH
linia sterująca DTR w łączu szeregowym RS232C stosowana jest przesyłania informacji o gotowości do przesyłania danych; wpisanie 1 na bit nr 0 portu 2FCH powoduje pojawienie się na linii DTR napięcia + 12V, wpisanie 0 — napięcia 12V;
poniżej przykład nietypowego zastosowania tej linii do włączania/wyłączania żarówki sygnalizacyjnej sterowanej poprzez łącze COM2;
zapalenie lampki: zgaszenie lampki
mov dx, 2FCH mov dx, 2FCH
mov al, 1 mov al, 0
out dx, al out dx, al
w typowych zastosowaniach łącze RS232C używane jest do transmisji szeregowej, zwykle dwukierunkowej;
w asynchronicznej transmisji szeregowej każdy przesyłany bajt stanowi samodzielną jednostkę informacji, zawierająca także bity dodatkowe: bit startu, bit stopu i ewentualnie bit kontrolny, który służy do kontroli poprawności transmisji;
poniżej podano przykład ilustrujący przesyłanie znaku [ o kodzie 91 = (01011011)2; w przypadku przesyłania danych przyjęto, że bitowi o wartości 1 odpowiada sygnał 12V, a bitowi o wartości 0 sygnał + 12V;
Sterowanie pracą urządzeń zewnętrznych komputera
komunikacja z urządzeniami realizowana poprzez odczyt i zapis rejestrów urządzeń dostępnych na poziomie instrukcji programu;
zlecenie by urządzenie wykonało pewną operację wymaga podjęcia następujących działań:
sprawdzenie stanu urządzenia;
wysłanie odpowiednich poleceń do urządzenia, o ile znajduje się ono w stanie gotowości;
przesłania (lub odczytania) danych;
sprawdzenie czy urządzenie wykonało polecenie:
1. metoda przeglądania (odpytywania),
2. metoda przerwaniowa
metoda przeglądania polega na wielokrotnym odczytywaniu stanu urządzenia, aż do chwili gdy odczytany stan wskazywać będzie na zakończenie operacji; metoda przeglądania jest nieefektywna i jałowo pochłania czas pracy procesora; trzeba też brać pod uwagę możliwość, że oczekiwane zdarzenie może wystąpić po bardzo długim czasie lub w ogóle nie wystąpić;
jeśli nawet sprawdzenie urządzenia wykonywane jest w pewnych odstępach czasu, to:
występują przerwy w obsłudze urządzenia, które zakłócają płynność jego pracy — urządzenie musi czekać na obsługę, co nie zawsze jest dopuszczalne (np. w transmisji szeregowej RS232 nieodczytany bajt zostaje zamazany przez kolejny przyjęty);
z kolei zwiększenie częstotliwości sprawdzania zwiększa straty czasu procesora; zazwyczaj dobór optymalnej częstotliwości sprawdzania jest trudny;
metoda przerwaniowa — urządzenie sygnalizuje zakończenie operacji (albo niezdolność do dalszego jej wykonywania) za pomocą sygnału przerwania skierowanego do procesora; sygnał przerwania powoduje przerwanie wykonywania aktualnego programu i przejście do wykonania podprogramu obsługi urządzenia, właściwego dla przyjętego przerwania;
odpowiednie środki sprzętowe i programowe powinny zapewnić możliwość wznowienia wykonywania przerwanego programu po zakończeniu podprogramu obsługi urządzenia; można powiedzieć, że przerwanie powinno być niewidoczne dla aktualnie wykonywanego programu, powodując jedynie jego chwilowe zatrzymanie;
metoda przerwaniowa jest zazwyczaj trudniejsza do zaprogramowania, ale jest znacznie bardziej efektywna.
Przerwania sprzętowe
w procesorach Pentium po wystąpieniu przerwania sprzętowego, bezpośrednio przed uruchomieniem programu obsługi przerwania na stosie zapisywany jest ślad, który umożliwia powrót do przerwanego programu; struktura śladu jest identyczna jak w przypadku instrukcji INT;
podprogram obsługi przerwania kończy instrukcja IRET, która powoduje wznowienie wykonywania przerwanego programu poprzez odtworzenie rejestrów (E)IP, CS i (E)FLAGS, na podstawie śladu zapamiętanego na stosie;
znacznik IF (ang. interrupt flag) w rejestrze znaczników (bit nr 9) określa zezwolenie na przyjmowanie przerwań: procesor może przyjmować przerwania tylko wówczas, gdy IF=1; znacznik IF jest automatycznie zerowany w chwili przyjęcia przerwania;
możliwe jest zablokowanie przyjmowania przerwań poprzez wyzerowanie znacznika IF; w programie do zmiany stanu znacznika IF można zastosować instrukcje CLI (IF 0) lub STI (IF 1); instrukcja IRET odtwarza stan rejestru znaczników (w tym IF) wg stanu zapamiętanego na stosie w chwili przyjęcia przerwania;
zazwyczaj każde urządzenie dołączone do komputera jest w stanie generować sygnały przerwań; wymaga to odpowiedniego zorganizowania systemu przerwań, tak poszczególne przerwania były przyjmowane wg ustalonej hierarchii; na ogół procesor nie jest przygotowany do bezpośredniej obsługi przerwań, zwłaszcza jeśli jest zainstalowanych dużo urządzeń;
stosowane są różne systemy obsługi przerwań; niekiedy zainstalowana jest wspólna linia przerwań dla wszystkich urządzeń — po nadejściu przerwania procesor sprawdza stany poszczególnych urządzeń identyfikując urządzenie, które wysłało przerwanie (metoda odpytywania); w innych systemach linia przerwań przechodzi przez wszystkie zainstalowane urządzenia ustawione wg priorytetów;
w komputerach PC system przerwań obsługiwany jest przez dwa układy typu 8259, którą pełnią rolę "sekretarki" procesora; sygnały przerwań z poszczególnych urządzenia kierowane są do układów 8259 poprzez linie oznaczone symbolami IRQ 0 IRQ 15;
z każdą linią IRQ (ang. interrupt request) skojarzony jest wektor przerwania w tablicy wektorów (deskryptorów) przerwań; skojarzenie to wykonywane poprzez odpowiednie zaprogramowanie układu 8259 — wykonuje to system operacyjny podczas inicjalizacji; typowe przyporządkowanie stosowane w systemie DOS podane jest poniższej tabeli; w systemie Windows używane są deskryptory (wektory) 50H 5FH, zaś w systemie Linux 20H 2FH;
IRQ |
Urządzenie |
Nr wek-tora |
|
IRQ |
Urządzenie |
Nr wek-tora |
0 |
zegar systemowy |
8 |
|
8 |
zegar czasu rzeczywistego |
112 |
1 |
klawiatura |
9 |
|
9 |
|
113 |
2 |
|
|
|
10 |
|
114 |
3 |
COM2 |
11 |
|
11 |
|
115 |
4 |
COM1 |
12 |
|
12 |
|
116 |
5 |
LPT2 |
13 |
|
13 |
koprocesor arytmetyczny |
117 |
6 |
dysk elastyczny |
14 |
|
14 |
dysk twardy |
118 |
7 |
LPT1 |
15 |
|
15 |
|
119 |
nadejście sygnału IRQ, np. IRQ 1 powoduje przerwanie i uruchomienie podprogramu obsługi przerwania, którego adres znajduje się w wektorze: 9 (DOS), 51H (Windows), 21H (Linux);
zazwyczaj przerwania generowane przez różne urządzenia mają przypisane priorytety; w komputerach PC priorytety poszczególnych przerwań mogą być ustalone poprzez odpowiednie zaprogramowanie układu 8259; w podanej tabeli mniejsze liczby oznaczają wyższe priorytety; przerwania aktualnie nie obsłużone zostaną obsłużone w dalszej kolejności;
IRQ |
Priorytet |
0 |
0 |
1 |
1 |
2 |
10 |
3 |
11 |
4 |
12 |
5 |
13 |
6 |
14 |
7 |
15 |
8 |
2 |
9 |
3 |
10 |
4 |
11 |
5 |
12 |
6 |
13 |
7 |
14 |
8 |
15 |
9 |
możliwe jest również przerwanie programu obsługi przerwania, jeśli nadejdzie przerwanie o wyższym priorytecie i podjęcie obsługi tego "ważniejszego"; jednak warunkiem przyjęcia przerwania jest stan znacznika IF=1 — ponieważ jednak przyjęcie przerwania gasi znacznik IF, więc nadejście "ważniejszego" przerwania nie będzie miało dalszych skutków aż do chwili w programie obsługi przerwania "mniej ważnego" nastąpi wpisanie IF 1; praktycznie: w programie obsługi przerwania, przed wykonaniem dalszych operacji o charakterze pomocniczym wykonywana jest instrukcja STI — po jej wykonaniu możliwe jest przyjmowanie innych przerwań;
w systemie DOS przerwanie z zegara systemowego (IRQ 0) generowane jest co około 55 ms, w systemie Linux co około 10 ms (10.0002 ms); przerwanie to odgrywa istotną rolę w trakcie pracy systemu operacyjnego, zapewniając systemowi operacyjnemu "poczucie upływu czasu";
zegar czasu rzeczywistego RTC (ang. real time clock) stanowi odrębny podzespół komputera, który udostępnia aktualną datę i czas; układ wykonany jest w technologii CMOS, co zapewnia mały pobór energii — w czasie gdy komputer nie pracuje, zegar CMOS RTC zasilany jest małej baterii;
odczyt i zapis zawartości zegara RTC dokonywany jest poprzez porty 70H i 71H; wygodniej jest korzystać z funkcji usługowych BIOSu dostępnych poprzez wektor przerwania 1AH;
przerwanie z zegara czasu rzeczywistego (IRQ 8) występuje tylko wyjątkowo, jeśli została w zegarze RTC została zaprogramowana operacja "budzenia" o ustalonej godzinie;
omówione wyżej przerwania mogą być blokowane poprzez wyzerowanie znacznika IF, wobec czego zaliczane są do klasy przerwań maskowalnych; procesor Pentium może też przyjmować przerwania niemaskowalne, które nie mogą być blokowane; przerwania niemaskowalne (ang. NMI — non-maskable interrupt) stosuje do sygnalizacji zdarzeń wymagających natychmiastowej obsługi niezależnie od stanu systemu; w komputerach PC przerwanie niemaskowalne generowane jest w przypadku zidentyfikowania błędu pamięci RAM.
Ewolucja systemów obsługi urządzeń wejścia-wyjścia
w trakcie wieloletniego rozwoju techniki komputerowej wyłoniło się wiele różnych sposobów obsługi urządzeń o różnym stopniu złożoności;
poniżej przedstawiono klasyfikację sposobów obsługi o wzrastającym stopniu złożoności:
1. procesor bezpośrednio steruje urządzeniem;
2. procesor steruje urządzeniem za pomocą sterownika urządzenia;
3. procesor steruje urządzeniem wykorzystując także przerwania;
4. dane do/z urządzeń przesyłane są za pomocą DMA;
5. układ wejścia-wyjścia sterowany jest przez specjalizowany procesor (czasami układ tego rodzaju nazywany jest kanałem wejścia-wyjścia);
6. specjalizowany procesor uzyskuje własną pamięć i sam staje się komputerem;
przykładem rozwiązań (1)(2)(3) może być technika wysyłania bajtów za pomocą łącza szeregowego w standardzie RS232C:
przesłanie bajtu realizowane jest poprzez wysyłanie, z ustaloną prędkością, kolejnych bitów począwszy od najmłodszego do najstarszego;
ponadto, przesyłany bajt poprzedzany jest bitem startu i zakończony bitem stopu; opcjonalnie może być wprowadzony bit kontroli parzystości;
w przypadku (1) procesor wprowadza linię wyjściową RS232C w odpowiedni stan, po czym wchodzi w pętlę trwającą przez ustalony czas, następnie ponownie wpisuje wartość kolejnego bitu na linię wyjściową i wchodzi w pętlę; proces ten powtarza się dla każdego przesyłanego bitu (łącznie z bitami startu i stopu);
rozwiązanie (1) w pełni angażuje procesor, przy czym, przez prawie cały czas przesyłania bajtu, procesor wykonuje kod jałowej pętli; z tego względu w wielu komputerach (m.in. w PC) stosuje się układ UART (np. 8250, 16550), który samodzielnie zajmuje się nadawaniem bajtu z zadaną prędkością; w tym przypadku (2) procesor wysyła bajt do układu UART, i po upływie pewnego czasu powinien sprawdzić, czy bajt został już wysłany — takie sprawdzenie w mniejszym stopniu angażuje procesor niż w przypadku (1), ponieważ może on w czasie między sprawdzeniami wykonywać "coś pożytecznego";
jednak znacznie bardziej efektywne jest rozwiązanie (3), w którym używane są przerwania — układ UART sygnalizuje zakończenie operacji nadawania poprzez wysłanie sygnału przerwania;
przykładem rozwiązania (5) jest sterowanie klawiatury w komputerach PC;
najbardziej zaawansowane rozwiązanie (6) może w istotny sposób zmniejszyć obciążenie głównego procesora; jeśli każde urządzenie zarządzane jest przez specjalizowany procesor, to można zrezygnować z systemu przerwań.
Wyjątki procesora
w trakcie wykonywania programu przez procesor występują sytuacje uniemożliwiające dalsze wykonywanie programu, np. niezidentyfikowany kod instrukcji, próba zmiany zawartości lokacji poza dozwolonym adresem, itd.; wystąpienie takich sytuacji powoduje wygenerowanie wyjątku przez procesor;
o ile przerwania powstają wskutek zdarzeń zewnętrznych w stosunku do procesora, to wyjątki związane są z wykonywaniem instrukcji przez procesor;
wyjątek procesora powoduje zapamiętanie śladu na stosie, wyzerowanie znacznika IF i rozpoczęcie wykonywania podprogramu właściwego dla określonego wyjątku; większość wyjątków zdefiniowana jest dla trybu chronionego; najbardziej znany wyjątek spowodowany wskutek wystąpienia nadmiaru przy dzieleniu zdefiniowany jest w trybie rzeczywistym i chronionym — powoduje on rozpoczęcie wykonywania podprogramu, którego adres znajduje się w wektorze (deskryptorze) przerwań nr 0.
Przerwania sprzętowe i programowe
występują pewne podobieństwa między przerwaniem sprzętowym a wykonaniem instrukcji INT: identyczna struktura śladu zapamiętywanego na stosie, zerowanie znacznika IF, korzystanie z tablicy wektorów przerwań; jednak istotna różnica polega na tym, że przerwanie sprzętowe jest niezależne od woli programu, natomiast wykonanie instrukcji INT, czyli przerwania programowego zależy od woli programu;
analiza działania instrukcji INT pozwala stwierdzić, że instrukcja ta wykonuje czynności charakterystyczne dla instrukcji wywołujących podprogramy: zapamiętanie śladu na stosie i przekazanie sterowania (skok) do podprogramu — stanowi ona więc odmianę instrukcji CALL typu FAR z adresowaniem pośrednim;
w trybie rzeczywistym procesora, w przypadkach gdy użycie instrukcji INT jest niewskazane, zastępuje się ją instrukcją CALL typu FAR poprzedzoną dodatkowo instrukcją PUSHF (ażeby ślad na stosie miał taką samą postać jak przy oryginalnym INT);
podprogramy systemowe wywoływane za pomocą instrukcji INT nazywa się często i nieściśle przerwaniami; taka terminologia zamazuje różnice między przerwaniami sprzętowymi a zleceniami wysyłanymi przez program za pomocą instrukcji INT; w odniesieniu do procedur obsługujących zlecenia wysyłane przez program lepiej używać terminu "funkcje (lub usługi) systemowe" albo "przerwania programowe".
w środowisku systemu DOS podprogramy systemowe nie są chronione w szczególny sposób i mogą być także wywoływane niestandardowo; inna sytuacja występuje w komputerach pracujących wieloprogramowo, gdzie konieczna jest ochrona podprogramów systemowych przez przypadkowym lub zamierzonym uszkodzeniem przez program użytkownika;
w komputerach wieloprogramowych podprogramy systemu operacyjnego mają znacznie większe uprawnienia niż zwykłe programy; z tego powodu konieczna jest automatyczna zmiana uprzywilejowania w chwili wywołania podprogramu systemowego; taka zmiana uprzywilejowania następuje także po przyjęciu przerwania sprzętowego; oznacza to, że w tego systemach instrukcja wywołująca podprogram systemowy nie może być zastąpiona przez inne instrukcje o podobnym działaniu;
w przeszłości używano także terminu ekstrakod w odniesieniu do instrukcji wywołujących podprogramy systemowe — termin ten, obecnie nieużywany, pozwalał na wyraźne odróżnienie wywołania podprogramu systemowego od przerwania sprzętowego;
podane tu rozważania nie zmieniają jednak faktu, że:
"Przerwania programowe ... są to w rzeczywistości przerwania grzecznościowe ... które niczego nie przerywają". (J. Duntemann, "Zrozumieć asembler", 1993).
27