ask3, Edukacja, studia, Semestr IV, Architektura Systemów Komputerowych, Wyklad


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;

0x08 graphic

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)

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 ;

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

cmp bx, cx

ja wieksze

— — — —

— — — —

wieksze:

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

ADD BH, BL

w wyniku dodawania uzyskamy wartość

0011 1001

1111 1111

0011 1000

Mnemonik

Testowany warunek

jc

CF = 1

jnc

CF = 0

jo

jno

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

0x01 graphic

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

0x01 graphic

0x01 graphic

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

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;

BSF

poszukiwanie bitu jedynkowego (w prawo)

BSR

poszukiwanie bitu jedynkowego (w lewo)

Przesunięcia bitowe

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

0x01 graphic

0x01 graphic

0x01 graphic

Wyodrębnianie pól bitowych

0x01 graphic

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ą;

0x01 graphic

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:

0x01 graphic

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;

0x01 graphic

w przypadku ogólnym wartość liczby zmiennoprzecinkowej (różnej od zera) określa wyrażenie:

0x01 graphic

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)

0x01 graphic

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);

0x01 graphic

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);

0x01 graphic

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

0x01 graphic

1023 = 3FFH dla formatu 64-bitowego, czyli

0x01 graphic

127 = 7FH dla formatu 32-bitowego, czyli

0x01 graphic

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;

Przykład kodowania liczby zmiennoprzecinkowej

Kodowanie liczby 12.25 w formacie 32-bitowym

Liczbę 12.25 przedstawiamy w postaci iloczynu 0x01 graphic
. Wykładnik potęgi k musi być tak dobrany, by spełniony był warunek normalizacji mantysy 0x01 graphic
, czyli

0x01 graphic

Łatwo zauważyć, że warunek normalizacji jest spełniony, gdy k = 3. Zatem

0x01 graphic

Ponieważ część całkowita mantysy nie jest kodowana, więc w polu mantysy zostanie wpisana liczba 0x01 graphic
, zaś w polu wykładnika (po przesunięciu o 127) liczba 0x01 graphic
. Ostatecznie otrzymamy

0x01 graphic

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);

FPTAN

tg = p/q

ST(0)

/31.047

q 1

ST(0)

ST(1)

x

p 1.730x01 graphic

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

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;

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;

0x01 graphic

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

0x01 graphic

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;

0x01 graphic

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;

0x01 graphic

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;

0x01 graphic

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

0x01 graphic

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;

0x01 graphic

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;

0x01 graphic

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;

0x01 graphic

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;

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

0x01 graphic

0x01 graphic

0x01 graphic



Wyszukiwarka