Documente Academic
Documente Profesional
Documente Cultură
PREFAŢĂ ---------------------------------------------------------- 3
1 INTRODUCERE ----------------------------------------------- 5
1.1 Calculator şi informatică------------------------------ 5
1.2 Utilizarea sistemelor de calcul ----------------------- 6
1.3 Principii de funcţionare ------------------------------- 9
2
PREFAŢĂ
3
microcalculatoarelor, calculatoarelor personale, profesionale şi a staţiilor de
lucru.
Capitolul al 4-lea descrie câteva elemente de teleinformatică. În acest
context sunt prezentate conceptele de bază ale realizării transmisiei
informaţiei, moduri de transmisie, evoluţia şi principalele caracteristici ale
reţelelor de calculatoare şi tendinţele de standardizare în acest domeniu.
Capitolul al 5-lea se referă la arhitectura software a sistemelor de
calcul. Sunt prezentate aspectele comparative ale limbajului de asamblare şi
limbajelor de programare evoluate precum şi etapele dezvoltării unui
program într-un sistem de calcul.
Capitolul al 6-lea este dedicat prezentării succinte a structurilor de date,
cu referire la principalele tipuri şi structuri, fişiere şi baze de date.
Capitolul al 7-lea prezintă evoluţia, caracteristicile şi structura unui
sistem de operare modern.
Capitolul al 8-lea evidenţiază modalităţile de implementare a
conceptelor şi noţiunilor prezentate în cadrul capitolului al 7-lea pentru
realizarea sistemelor de operare DOS, Windows şi UNIX, care sunt printre
cele mai reprezentative din noua generaţie de sisteme.
Capitolul al 9-lea face referire la implementarea principalilor algoritmi
de reprezentare a informaţiilor în calculator, implementarea structurilor de
date şi câteva aplicaţii diverse. Aplicaţiile practice sunt realizate în limbajul
Java.
Lucrarea se încheie cu o bibliografie relativă la tema propusă.
Deoarece limba engleză este preponderent utilizată în informatică, am
menţionat termenii cei mai importanţi între paranteze drepte.
Cartea este suficient de detaliată şi prezintă într-un mod progresiv de la
simplu la complex noţiunile abordate, încât permite oricărei persoane, chiar
fără cunoştinţe preliminare, să se iniţieze în informatică.
Cartea se adresează în primul rând studenţilor de la secţiile cu profil
informatic din instituţiile de învăţământ superior, precum şi cadrelor
didactice şi elevilor din învăţământul preuniversitar care vizează iniţierea în
informatică sau aprofundarea anumitor noţiuni din acest domeniu.
4
1 INTRODUCERE
5
d) Generaţia a IV-a, specifică anilor ‘80, se caracterizează prin
utilizarea circuitelor integrate pe scară largă şi foarte largă, memorii
cu bule, discuri optice, limbaje de programare evoluate (Ada,
limbaje orientate obiect), memorii de mare capacitate, viteze de
calcul considerabile, apariţia supercalculatoarelor.
e) Generaţia a V-a, specifică anilor ‘90, are drept caracteristici
importante utilizarea circuitelor integrate pe scară extrem de largă,
utilizarea maşinilor Lisp şi Prolog, a arhitecturilor paralele,
programarea în limbaje concurente, limbajul natural, limbaje
funcţionale (Lisp) şi logice (Prolog), performanţele relative la
memorie şi viteza de calcul făcând posibilă memorarea şi
prelucrarea cunoştinţelor (inteligenţa artificială).
Arhitectura unui sistem de calcul se referă la descrirea unităţilor sale
funcţionale şi interconexiunile dintre acestea.
Configuraţia unui sistem de calcul corespunde organizării adoptate pentru
a asambla şi a face să funcţioneze diversele entităţi materiale (procesoare,
memorie, terminale, imprimante, unităţi de disc etc.) ale sistemului.
6
matematice uzuale (statistică, calcul matricial, calcul integral şi
diferenţial etc.).
b) gestiunea economică, care necesită capacităţi de memorare şi de
prelucrare a unui volum mare de informaţii, structurate în înregistrări
care se găsesc în fişiere stocate pe discuri sau benzi magnetice. O
abordare mai sofisticată a gestiunii informaţiilor constă în a utiliza
sisteme de baze de date, care asigură stocarea înregistrărilor şi
accesarea acestora, permiţând interogări destul de complexe.
c) conducerea proceselor, care necesită în general sisteme de calcul
sau procesoare specializate în achiziţionarea datelor şi controlul în
timp real al aparatelor de o oarecare complexitate (de exemplu,
unităţi industriale, maşini de spălat, carburatoare de maşini etc.).
Se pot distinge de asemenea mai multe moduri de funcţionare ale unui
sistem de calcul:
a) pe loturi de lucrări batch, prin care sistemul de calcul execută în
mod secvenţial un lot de programe, fără a permite interacţiunea cu
utilizatorul;
b) timp partajat time sharing, prin care sistemul de calcul oferă
utilizatorului „iluzia” prelucrării mai multor programe simultan,
datorită posibilităţii de a aloca mici tranşe de timp fiecărui
program al utilizatorului. Aceste sisteme interactive sunt cele mai
apropiate de utilizatori, deoarece aceştia pot dialoga cu sistemul
de calcul într-un anumit limbaj de comandă, cu ajutorul unui
terminal (ecran + tastatură). Sistemele tranzacţionale stabilesc o
colaborare între sistemele conversaţionale şi sistemele de
gestiune care coordonează accesul la mari baze de date;
c) timp real real time, prin care timpul de răspuns al sistemului de
calcul la diferite solicitări joacă un rol important, fiind un factor critic.
Sistemele care asigură conducerea proceselor funcţionează în general
în timp real (de exemplu, comenzile electronice ale unui avion).
Programarea este activitatea care constă în a scrie o secvenţă de
instrucţiuni într-un anumit limbaj înţeles de către sistemul de calcul. Mai
general vorbind, programarea constă în următoarele: pornind de la o
problemă dată să se realizeze un program a cărui execuţie să conducă la o
soluţie satisfăcătoare a problemei puse.
Activitatea de programare se descompune în mai multe faze, care
constituie ciclul de viaţă al unui software:
a) enunţul şi înţelegerea problemei;
b) specificarea (descrierea funcţionalităţilor sistemului);
7
c) concepţia (descompunerea modulară a problemei în subprobleme,
elaborarea algoritmilor etc.);
d) programarea (faza de codificare a programului);
e) testarea şi validarea (se verifică dacă programul realizează, fără
erori, funcţionalităţile specificate);
f) întreţinerea (asigurarea actualizărilor necesare pe întreaga durată a
exploatării).
O fază foarte importantă este cea de asigurare a documentaţiei tehnice
necesare şi ea se efectuează în paralel cu toate celelalte faze.
Un algoritm este o succesiune de acţiuni (instrucţiuni) destinate
rezolvării unei probleme într-un număr finit de operaţii.
Primele programe erau scrise în limbaj maşină (cod binar pur), apoi s-a
utilizat limbajul de asamblare care are avantajul folosirii mnemonicelor şi
simbolurilor.
Limbajele de programare evoluate cum ar fi Fortran, Pascal,
Modula-2, Ada, C, C++ (limbaje ştiinţifice), şi Cobol, PL/I (limbaje de
gestiune) au permis dezvoltarea unor mari produse software.
Limbajele Lisp şi Prolog sunt limbaje ale inteligenţei artificiale care
permit realizarea sistemelor expert şi a căror caracteristică principală este
realizarea simulării inteligenţei umane.
Un program este constituit din diverse tipuri de instrucţiuni care pot
realiza următoarele operaţii:
a) operaţii de intrare / ieşire I/O: Input/Output: de exemplu,
trimiterea unui caracter spre o imprimantă, spre un ecran, într-un
fişier memorat pe disc sau citirea de pe suport magnetic;
b) operaţii de calcul aritmetic: +, -, , /, ...
c) operaţii de calcul logic: and, or, not;
d) operaţii de salt: fie condiţionat, ca de exemplu instrucţiunea clasică
If …Then … Else (aceste operaţii sunt importante deoarece permit
parcurgeri de drumuri diferite în funcţie de rezultatul comparărilor şi
deci de a simula o anumită inteligenţă), fie necondiţionat, de
exemplu apelul unui subprogram.
Un program scris în limbaj evoluat există sub forma unui cod sursă. Pentru a
putea fi executat pe un sistem de calcul, acest cod sursă parcurge următoarele
etape: compilarea, editarea de legături şi încărcarea în memoria centrală.
Compilatorul este un program care transformă un modul în cod sursă
într-un modul în cod obiect (cod maşină).
Editorul de legături este programul care asigură „legarea” diferitelor
module ale unui program cum ar fi subprograme, module din biblioteca
sistemului etc.
8
Încărcătorul este destinat transferării unui program complet şi gata de
execuţie din memoria auxiliară în memoria centrală.
1.3 Principii de funcţionare
Un sistem de calcul se compune dintr-o memorie centrală, care conţine
programele şi datele, o unitate centrală de prelucrare care execută un
program încărcat în memoria centrală, unităţi de intrare / ieşire care permit
schimbul de informaţii cu unităţile periferice. Vom numi unitate centrală
ansamblul constituit din unitatea centrală de prelucrare şi memoria centrală.
Execuţia unui program se derulează potrivit următorului model:
a) programul şi datele aferente sunt încărcate în memoria centrală;
b) instrucţiunile programului sunt aduse secvenţial unităţii de control
care le analizează şi declanşează prelucrarea corespunzătoare,
trimiţând în acest sens semnale către unitatea aritmetică şi logică;
c) prelucrarea poate să necesite un apel la unităţile de intrare / ieşire
sau la memoria centrală.
Schema generală a unui sistem de calcul este prezentată în continuare.
unitatea centrală
de prelucrare
instrucţiuni
unitatea de control memoria centrală
şi de comandă
date
unitatea de calcul
unităţi de intrare/ieşire
controler de
periferice
unităţi periferice
9
Biţii se regrupează câte 6, 7 sau 8 pentru a forma un caracter. Un caracter
constituit dintr-o succesiune de 8 biţi se numeşte octet byte.
În paralel cu caracterele, care constituie o unitate logică de informaţie,
memoria centrală a sistemului de calcul este divizată fizic în locaţii, iar
fiecărei locaţii îi corespunde un cuvânt de memorie care posedă o adresă
proprie. Lungimea unui cuvânt de memorie variază de la un sistem de calcul
la altul, dar valorile 32 şi 64 tind să se generalizeze în majoritatea sistemelor
de calcul. Lungimea unui cuvânt de memorie este o caracteristică
importantă a arhitecturii unui sistem de calcul şi reflectă structura
componentelor sale funcţionale (în special unitatea centrală).
Un cuvânt de memorie word este unitatea adresabilă de informaţie,
adică orice operaţie de citire sau de scriere se realizează asupra unui cuvânt.
Fiecărui cuvânt de memorie îi sunt deci asociate: o adresă (unică),
indicând poziţia sa în memorie şi un conţinut (instrucţiune sau dată).
Capacitatea unei memorii se poate exprima în funcţie de numărul de
cuvinte de memorie ca şi de numărul de biţi dintr-un cuvânt.
Un registru este o locaţie de memorie având o funcţie particulară. În
memoria centrală se găsesc două tipuri de registre: registru de adresă, care
conţine adresa unui cuvânt de memorie şi registru cuvânt, care păstrează
conţinutul unui cuvânt de memorie.
Un registru cuvânt are aceeaşi mărime cu un cuvânt de memorie, în timp
ce un registru de adresă trebuie să permită adresarea tuturor cuvintelor.
Operaţiile posibile în memoria centrală sunt citirea şi scrierea unui
cuvânt de memorie:
a) citirea: registrul de adresă conţine adresa cuvântului de citit, iar o
copie a conţinutului este transferată în registrul cuvânt;
b) scrierea: registrul de adresă conţine adresa unui cuvânt în care se va
scrie conţinutul registrului cuvânt.
Timpul necesar scrierii sau citirii unui cuvânt de memorie se numeşte
timp de acces (de ordinul nanosecundelor şi microsecundelor).
Dacă timpul de acces este identic pentru fiecare cuvânt al memoriei
centrale, atunci avem de-a face cu o memorie RAM Random Access
Memory, adică o memorie cu acces aleator sau acces direct.
Unitatea centrală de prelucrare (CPU) este constituită din unitatea de
comandă şi unitatea de calcul.
Unitatea de comandă asigură controlul execuţiei instrucţiunilor unui
program şi conţine două registre importante:
a) registru de instrucţiuni (RI) care conţine adresa instrucţiunii în
curs de execuţie (o instrucţiune comportă mai multe câmpuri: un
câmp cod – operaţie şi între 0 şi 3 câmpuri operand);
10
b) registru contor ordinal (CO) care conţine adresa următoarei
instrucţiuni de executat. În general, instrucţiunile se succed
secvenţial iar CO se incrementează cu o unitate la fiecare ciclu
CPU, pentru a obţine adresa instrucţiunii următoare. În anumite
situaţii (de exemplu pentru instrucţiunile de salt) este necesară
forţarea valorii contorului ordinal.
Unitatea de comandă conţine de asemenea un dispozitiv de decodificare
a instrucţiunilor (decodificator) şi un dispozitiv de control al secvenţei de
comenzi care activează circuitele necesare execuţiei instrucţiunii curente.
Înlănţuirea comenzilor se realizează prin intermediul unui ceas sistem.
Unitatea de calcul sau aritmetică şi logică (UAL) conţine toate
circuitele electronice care realizează efectiv operaţiile dorite. Operanzii
acestor operaţii se găsesc în registrele unităţii.
Registrele UAL se divizează în diverse categorii:
a) registre aritmetice: servesc efectuării operaţiilor aritmetice;
b) registre de bază şi index: permit calculul de adresă în raport cu o
valoare de bază sau un index;
c) registre generale: realizează diverse operaţii cum ar fi stocarea
rezultatelor intermediare;
d) registrul de stare PSW: Program Status Word: indică starea
sistemului la un moment dat.
Unităţile de intrare / ieşire (I / O) sunt elemente care premit transferul
informaţiilor între unitatea centrală şi unităţile periferice. Unităţile de intrare
/ ieşire cele mai cunoscute sunt: unităţile de tip bus, cele care asigură acces
direct la memorie DMA: Direct Memory Access şi unităţile de canal.
Unităţile periferice se repartizează în două clase:
a) unităţi de transfer care permit sistemului de calcul să realizeze
schimburi de date cu exteriorul (ecran, tastatură, imprimantă etc.);
b) memoriile auxiliare (discuri, benzi, cartuşe magnetice etc.) care
permit stocarea permanentă a unui volum mare de informaţii la un
preţ scăzut; ele se utilizează datorită faptului că memoria centrală
este volatilă şi informaţiile se şterg când se opreşte sistemul, pe când
suporturile magnetice sunt memorii permanente.
În concluzia acestui capitol vom prezenta două aspecte simple care
exprimă faptul că un sistem de calcul este o maşină care execută la nivelul
său de bază decât operaţii elementare:
a) Toate sistemele de calcul se compun în principal din milioane sau
chiar miliarde de tranzistoare care nu pot efectua decât operaţii
elementare foarte rapid;
11
b) Un sistem de calcul este o maşină care trebuie programată corect,
adică trebuie prevăzut şi explicat absolut tot ceea ce el trebuie să
realizeze repede şi bine.
2 MODELE DE DATE ÎN SISTEMELE DE CALCUL
Date nenumerice
Datele nenumerice corespund caracterelor alfanumerice: A, B, ..., Z, a,
b, ..., z, 0, 1, 2, ..., 9 şi caracterelor speciale: ?, !, “, $, ;, ...
Codificarea se realizează pe baza unei tabele de corespondenţă specifică
fiecărui cod utilizat. Printre cele mai cunoscute coduri putem enumera:
BCD Binary Coded Decimal prin care un caracter este codificat pe 6 biţi;
ASCII American Standard Code for Information Interchange(7 biţi);
EBCDIC Extended Binary Coded Decimal Internal Code (8 biţi).
Figura următoare prezintă corespondenţa dintre diferite coduri.
12
caracter BCD ASCII EBCDIC
0 000000 0110000 11110000
1 000001 0110001 11110001
2 000010 0110010 11110010
... ... ... ...
9 001001 0111001 11111001
A 010001 1000001 11000001
B 010010 1000010 11000010
C 010011 1000011 11000011
(6 biţi) (7 biţi) (8 biţi)
Datele numerice
Datele numerice sunt de următoarele tipuri:
a) numere întregi pozitive sau nule: 0; 1; 315...
b) numere intregi negative: -1; -155...
c) numere fracţionare: 3.1415; -0.5...
d) numere în notaţie ştiinţifică: 4.9 107 ; 1023 ...
Codificarea se realizează cu ajutorul unui algoritm de conversie asociat
tipului de dată corespunzător. Operaţiile aritmetice (adunare, scădere,
înmulţire, împărţire) care se pot aplica asupra acestor date se efectuează de
regulă în aritmetica binară. Figura de mai jos arată regulile operaţiilor binare.
0+0=0 00=0
0+1=1 01=0
1+0=1 10=0
1 + 1 = 10 11=1
Sisteme de numeraţie
Un sistem de numeraţie face să-i corespundă unui număr N, un anumit
simbolism scris şi oral. Într-un sistem de numeraţie cu baza p > 1, numerele
0, 1, 2, ..., p –1 sunt numite cifre.
Orice număr întreg pozitiv poate fi reprezentat astfel:
N = anpn + an-1pn-1 + ... + a1p + a0
cu ai 0, 1, 2, p-1 şi an 0.
13
Se utilizează de asemenea notaţia echivalentă N = anan-1...a1a0.
Numerele scrise în binar sunt adesea compuse dintr-un mare număr de biţi,
şi de aceea se preferă exprimarea acestora în sistemele octal (p = 8) sau
hexazecimal (p = 16), deoarece conversia cu sistemul binar este foarte simplă.
Schimbări de bază
a) binar zecimal
Conversia se realizează prin însumarea puterilor lui 2 corespunzătoare
biţilor egali cu 1;
Exemplu: 101012= 24 + 22 + 20 = 16 + 4 + 1 = 2110
b) zecimal binar
Conversia se efectuează prin împărţiri întregi succesive cu 2. Testul de
oprire corespunde situaţiei câtului nul. Numărul binar este obţinut
considerând resturile în ordinea inversă.
Exemplu: Conversia lui 26:
26 : 2 = 13 rest 0
13 : 2 = 6 rest 1
6:2=3 rest 0
3:2=1 rest 1
1:2=0 rest 1
Se obţine (de jos în sus): 2610 = 110102.
c) octal (hexazecimal) zecimal
Conversia se reduce la însumarea puterilor lui 8 (16).
d) zecimal octal (hexazecimal)
Conversia se efectuează prin împărţiri întregi succesive prin 8 (16). Testul
de oprire corespunde situaţiei câtului nul. Numărul octal (hexazecimal) este
obţinut considerând resturile obţinute de la ultimul către primul.
e) octal (hexazecimal) binar
Conversia corespunde dezvoltării fiecărei cifre octale (hexazecimale) în
echivalentul ei binar pe 3 (4) biţi.
Exemplu: 278 = 010’1112 deoarece 28 = 0102 şi 78 = 1112.
3A16 = 0011’10102 deoarece 316= 00112 şi A16=10102.
f) binar octal (hexazecimal)
Conversia se realizează înlocuind de la dreapta la stânga, grupele de 3 (4)
biţi prin cifra octală (hexazecimală) corespunzătoare. Dacă numărul de biţi nu
este multiplu de 3 (4) se completează configuraţia binară la stânga cu zerouri.
Exemplu: 1010112= 538 = 2B16 .
14
semn şi valoare absolută (SVA);
complement logic sau restrâns sau faţă de 1 (C1);
complement aritmetic sau adevărat sau faţă de 2 (C2);
Prin metoda „semn şi valoare absolută“, numerele se codifică sub
forma: valoare absolută.
Prin această reprezentare se sacrifică un bit pentru semn. În mod normal,
0 este codul semnului „+”, iar 1 este codul semnului „-”. În aceste condiţii,
pe un cuvânt de k biţi se pot reprezenta numere întregi pozitive şi negative
N, astfel încât: - (2k-1- 1) N (2k-1- 1).
Această metodă de reprezentare prezintă unele inconveniente:
numărul zero are două reprezentări distincte: 000...0 şi 100...0, adică
+0 şi -0;
tabelele de adunare şi înmulţire sunt complicate din cauza bitului de
semn care trebuie tratat separat.
15
În complement faţă de 1 sau 2 nu se produce depăşire de capacitate decât
în cazul în care cifrele de transport generate de bitul de semn şi de bitul
anterior acestuia sunt diferite.
Se poate remarca faptul că bitul cel mai din stânga (bitul de semn) este
întotdeauna 0 pentru numere pozitive şi 1 pentru cele negative şi aceasta
pentru fiecare din cele trei reprezentări, conform tabelului următor.
Numere fracţionare
Numerele fracţionare sunt numerele subunitare.
Schimbări de bază
a) binar zecimal
Conversia se face adunând puterile (negative) corespunzătoare ale lui 2.
Exemplu: 0.012 = 0 2-1 + 1 2-2 = 0.2510.
b) zecimal binar
Conversia se efectuează prin înmulţiri succesive cu 2 a numerelor pur
fracţionare. Acest algoritm trebuie să se termine când se obţine o parte
fracţionară nulă sau când numărul de biţi obţinuţi corespunde mărimii
registrului sau a cuvântului de memorie în care se va stoca valoarea.
Numărul binar se obţine citind părţile întregi în ordinea calculării lor.
Exemplu: 0.125 2 = 0.250 = 0 + 0.250
0.25 2 = 0.50 = 0 + 0.50
0.50 2 = 1.0 = 1 + 0.0
Vom considera părţile întregi de sus în jos, deci: 0.2510= 0.0012.
16
Pentru numerele fracţionare se pot remarca reprezentările în virgulă fixă
şi virgulă mobilă.
SM ED M
17
unde SM este semnul mantisei, ED este exponentul decalat şi M mantisa.
Pentru nu număr de k biţi rezervaţi pentru ED se pot reprezenta fără
semn 2k valori, de la 0 la 2k – 1. Decalajul considerat este 2k-1, ceea ce
permite ca valorile de la 0 la 2k-1-1 pentru ED să corespundă unui exponent
real (ER) negativ, iar valorile de la 2k-1 la 2k – 1 ale lui ED să corespundă
unui exponent real (ER) pozitiv. Deci domeniul de valori reprezentabile
pentru exponentul real este de la –2k-1 la 2k-1-1.
De exemplu, pentru k = 4, pe cei 4 biţi putem reprezenta fără semn
numere de la 0 la 15 pentru ED. Decalajul considerat este 2 k-1 = 23 = 8, deci
pentru exponentul real (ER) putem considera valori de la - 2k-1 = -23 = -8 şi
până la 2 k-1 – 1 = 23 – 1 = 7.
Relaţia existentă se poate scrie astfel: ER = ED – D.
Exponentul determină intervalul de numere reprezentabile în sistemul de calcul,
iar numerele prea mari pentru a putea fi reprezentate corespund unei „depăşiri
superioare” de capacitate de memorare overflow, iar numerele prea mici
corespund unei „depăşiri inferioare” de capacitate de memorare underflow.
Mărimea mantisei exprimă precizia de reprezentare a numerelor.
Avantajul utilizării virgulei mobile faţă de virgula fixă constă în
intervalul mult mai extins al valorilor posibile de reprezentat.
18
INFORMAŢII
INSTRUCŢIUNI DATE
(diferite formate în cod maşină)
Numerice Nenumerice
Codificare prin tabele
BCD (6 biţi)
ASCII (7 biţi)
EBCDIC (8 biţi)
Numere fracţionare
Codul BCD
Codul BCD Binary Coded Decimal este unul dintre cele mai răspândite
coduri cu semnificaţia „zecimal codificat în binar”, în care fiecare cifră zecimală
este codificată în mod individual în echivalentul său binar pe patru biţi.
Orice cifră zecimală se poate reprezenta pe patru biţi, dar valorile
reprezentabile pe patru biţi sunt în număr de 24 = 16, deci vor rămâne 6
configuraţii neutilizate, de care trebuie să se ţină seama la efectuarea
operaţiilor aritmetice.
În situaţia operaţiei de adunare trebuie să se adauge 6, ori de câte ori
rezultatul este superior lui 9, iar pentru operaţia de scădere se va extrage 6
dacă rezultatul este negativ.
Exemplu: zecimal binar BCD
15+ 01111+ 0001’0101+
18 10010 0001’1000
--- ------- -------------
33 100001 0010’1101 > 9
(= 33) 0110 +6
-------------
0011’0011 (=33)
Operaţiile aritmetice sunt deci destul de complicate, dar operaţiile de
intrare / ieşire sunt uşor de realizat deoarece fiecare entitate BCD este direct
asociată unui caracter. Din aceste motive, codul BCD se găseşte în sistemele
de calcul de gestiune, unde operaţiile aritmetice sunt mult mai puţin
numeroase decât operaţiile de intrare / ieşire.
20
Codul BCD este un cod ponderat 8 – 4 – 2 – 1, cei patru biţi necesari
pentru a codifica o cifră au o pondere corespunzătoare cu poziţia lor,
respectiv 8 = 23 pentru bitul cu numărul 3, 4 = 22 pentru bitul cu numărul 2,
2 = 21 pentru bitul cu numărul 1 şi 1 = 20 pentru bitul cu numărul 0.
Codul „excedent – 3”
Codul „excedent - 3” nu este un cod ponderat, fiecare cifră zecimală este
codificată separat în echivalentul său binar + 3.
Exemplu: 12910 = 0100’0101’1100 excedent - 3
Avantajul acestui cod faţă de codul BCD este acela că operaţiile
aritmetice sunt mai simple.
De exemplu, complementarea faţă de 9 (similară în sistemul zecimal cu
complementarea faţă de 1 în sistemul binar) este imediată: este suficientă
complementarea fiecărui bit.
Codul „2 din 5”
Codul „2 din 5” este un cod neponderat în care fiecare cifră zecimală
este codificată pe 5 biţi, dintre care numai 2 au valoarea 1.
Exemplu: 12910 = 00101’00110’11000 cod „2 din 5”
Avantajul acestui cod este acela de detectare (nu şi corectare) a unei erori
sau a unui număr impar de erori.
Codul bicvintal
Codul bicvintal este un cod ponderat 50’43210 care permite detectarea
erorilor. O cifră zecimală este codificată printr-un număr binar pe 7 biţi,
având un singur bit egal cu 1 pe primele 2 poziţii din stânga şi un singur bit
egal cu 1 pe 5 poziţii cele mai din dreapta.
Exemplu: 12910 = 0100010’0100100’1010000 bicvintal.
21
Sursa → Codificator → Canal → Decodificator → Destinaţie
1 0 . . . 0 a11 . . . a1k
0 1 . . . 0 a21 . . . a2 k
Gm, n . ..
0 0 amk
. . . 1 am1 . . .
23
Definiţia 2.1
O aplicaţie C: B2m → B2n este un cod liniar binar de dimensiuni (n, m)
generat de o matrice G, dacă pentru orice secvenţă (s1, s2, ..., sm) din B2m,
codul acesteia se obţine astfel:
C((s1, s2, ..., sm))=(s1, s2, ..., sm) ∙ Gm,n
Din definirea înmulţirii matricelor şi din modul în care s-a definit
matricea generatoare G, rezultă că C((s1, s2, ..., sm)) este o secvenţă (vector)
din B2n .
După efectuarea înmulţirii, se obţine:
C((s1, s2, ..., sm)) = (s1, s2, ..., sm, c1, c2, ..., ck),
unde
m
cj s a
i 1
i ij , j 1, k
24
Plecând de la matricea generatoare Gm,n, se construieşte matricea de
control a codului Hk,n, având k linii şi n coloane:
a11 a21 am1 1 0 0
a12 a22 am 2 0 1 0
H k ,n
a
1k a 2 k a mk 0 0 1
Pentru codul (7, 4) definit mai sus, avem:
0 1 1 1 1 0 0
H 3, 7 1 0 1 1 0 1 0
1 1 0 1 0 0 1
Să notăm Am,k, Atk,m, In şi Om,n matricele de mai jos:
a11 a12 a1k
a21 a22 a2k
Am, k
a
m1 am 2 amk
a11 a21
am1
a a22
am 2
Akt , m 12
a amk
1k a2 k
1 0 0 0 0 0
0 1 0 0 0 0
In Om,n
0 0 1 0 0 0
În continuare, vom adopta scrierea „pe blocuri” a matricelor G şi H,
plecând de la matricele A şi I.
Gm,n = [Im| Am,k], Hk,n = [Atk,m | k].
Este uşor de văzut că transpusele acestora sunt:
I Am, k
Gnt , m tm GH nt , k
Ak , m Ik
Teorema 2.1
Au loc următoarele egalităţi:
25
Gm,n ∙ Htn,k = Om,k şi Hk,n ∙ Gtn,m = Ok,m
Înainte de a trece la demonstraţie, trebuie spus că în teoria codurilor,
aceste egalităţi sunt cunoscute sub numele de condiţii de ortogonalitate.
Pentru demonstraţie, este suficient să efectuăm înmulţirea „pe blocuri” a
matricelor. Dimensiunile matricelor ne permit acest mod de a opera.
Verificăm prima egalitate:
A
Gm,n ∙ Htn,k = [Im| Am,k] ∙ m, k = Im ∙ Am,k + Am,k ∙ Ik = Am,k + Am,k = Om,k
Ik
Verificăm şi a doua egalitate:
I
Hk,n ∙ Gtn,m = [Atk,m|Ik] ∙ tm = Atk,m ∙ Ik + Ik∙ Atk,m= Atk,m + Atk,m = Ok,m
Ak , m
Acest rezultat, împreună cu definiţia funcţiei de codificare liniară binară,
conduce la următorul rezultat:
Teorema 2.2
Pentru orice sursă s1, s2, ..., sm, are loc:
Hk,n ∙[C((s1, s2, ..., sm))] t = Ok,1
Demonstraţie:
Hk,n ∙ [C((s1, s2, ..., sm))] t = Hk,n ∙ [(s1, s2, ..., sm) ∙ Gm,n] t = Hk,n ∙ G tm,n ∙
(s1, s2, ..., sm) t = Ok,1
Din această teoremă rezultă criteriul de verificare a corectitudinii
transmisiei. Presupunem că de la sursă se emite C((s1, s2, ..., sm)), adică biţii:
(s1, s2, ..., sm, c1, c2, ..., ck),
şi se recepţionează biţii:
(s'1, s'2, ..., s'm, c'1, c'2, ..., c'k).
Să notăm Hk,n ∙ (s'1, s'2, ..., s'm, c'1, c'2, ..., c'k)t = (z1, z2, ..., zk)t. Acest
vector va fi numit vector de control sau sindrom.
Dacă vectorul de control al parităţii este vectorul nul, adică (z1, z2, ..., zk)t
= Ok,1 atunci la destinaţie s-a recepţionat un cod corect şi mesajul este
acceptat. În caz contrar, s-a detectat o eroare survenită în timpul transmisiei
şi mesajul nu este acceptat.
Definiţia 2.2
Capacitatea de detecţie a unui cod este dată de următorul raport:
Numar de cuvinte eronate detectabile prin cod
C
Numar total de cuvinte eronate
26
Acest raport are o valoare subunitară şi este cu atât mai bun cu cât
valoarea lui este mai apropiată de 1.
Să determinăm capacitatea de detecţie a unui cod liniar binar (n, m).
Mulţimea B2n are 2n elemente, iar mulţimea B2m are 2m elemente. Deci sursa
poate emite maximum 2m cuvinte de cod, cuvinte codificate cu vectori din
B2n. Astfel, un astfel de cod poate să detecteze ca eronate 2 n-2m elemente.
Numărul maxim de cuvinte eronate este evident 2n-1, adică toate cuvintele
posibile, cu excepţia celui care s-a transmis.
Capacitatea de detecţie a unui cod liniar binar este:
2n 2m 2m k 2m
C
2n 1 2m k 1
Să delimităm această valoare a lui C. Mai întâi, avem:
2n 2m 2m k 1
C n m k 1
2 1 2 1
Apoi,
2m k 2m 2m k 2m 2m 1
C m k m k
1 m k
1 k
2 1 2 2 2
În consecinţă,
1
1 k C 1
2
Această dublă delimitare a lui C este cu atât mai bună cu cât valoarea lui
k este mai mare, adică un cod liniar binar este cu atât mai bun cu cât sunt
mai mulţi biţi de control.
Acest număr de biţi nu poate fi oricât de mare. În definiţia matricei
generatoare G se precizează că ea trebuie să aibă coloane diferite, deci cu
siguranţă nu pot fi folosiţi mai mult de 2m biţi de control. Această delimitare
este exagerat de mare. Existenţa a prea mulţi biţi de control face ca mesajele
să fie exagerat de lungi, ceea ce face codul greu de manevrat.
Coduri iterative
În practică, pentru a se asigura o capacitate de detecţie mai mare, ca şi
pentru a avea siguranţa că este receptat cuvântul de cod emis de sursă, sunt
folosite codurile iterative (coduri încrucişate). Cel mai simplu cod de acest
fel presupune aplicarea bitului de paritate într-o matrice.
În acest scop, biţii mesajului sunt plasaţi într-o matrice, să zicem cu q
linii şi p coloane. Fie bij biţii mesajului. Pentru a se asigura controlul de
paritate încrucişat, se mai adaugă încă o linie şi o coloană la această matrice.
Matricea iniţială, la care s-au făcut aceste completări este:
27
b11 b11 b1 p | l1
b b12 b2 p | l2
21
|
bq1 bq1 bqp | lq
|
t1 t2 tp | r
Biţii t1, t2, ..., tp se numesc biţi de paritate transversală şi sunt astfel
aleşi, încât să fie asigurată paritatea fiecărei coloane. Ei verifică, pentru
fiecare j între 1 şi p (operaţiile sunt efectuate modulo 2):
q q
t j bij 0, deci t j bij , pentru j 1, p
i 1 i 1
Biţii l1, l2, ..., lq se numesc biţi de paritate longitudinală şi sunt astfel aleşi, încât
să fie asigurată paritatea fiecărei linii. Ei verifică, pentru fiecare j între 1 şi p:
p p
li bij 0, deci li bij , pentru i 1, q
j 1 j 1
Se pune în mod firesc întrebarea: bitul r, aflat în linia q+1 şi coloana p+1 a
matricei extinse satisface condiţia de paritate atât pentru linia q+1 cât şi pentru
coloana p+1? Răspunsul este afirmativ şi este dat de următoarea teoremă:
Teorema 2.3
Bitul r din codul iterativ, este bit de paritate atât pentru coloana de paritate
longitudinală l1, l2, ..., lq, cât şi pentru linia de paritate transversală t1, t2, ..., tp.
Demonstraţia este imediată şi are la bază proprietatea de comutativitate a
operatorului de sumare:
p p q q p q
r t j b ij b ij l i
j1 j1 i 1 i 1 j1 i 1
Deci bitul r este stabilit în mod unic.
De exemplu, pentru q = 3 şi p = 7, o matrice extinsă cu biţii de paritate
încrucişată este:
1 0 0 1 0 1 0 1 |
0 1 0 0 1 1 1 | 0
0 1 1 0 1 1 0 | 0
1 0 1 1 0 1 1 | 1
28
2.2.3 Structura unui bloc de informaţie pe suport magnetic
Tehnologia de înregistrare a informaţiilor pe suport magnetic (disc
magnetic şi optic, dischetă, bandă streamer etc.) prevede adăugarea
combinată a mai multor tehnici de a detecta şi eventual de a corecta erori.
Un bloc de informaţie pe un suport magnetic conţine o structură
complexă de control. Biţii de informaţie sij sunt dispuşi într-o matrice, care
este completată cu încă o linie şi k+1 coloane, astfel:
s11 s1m | c11 c1k | l1
| |
s q1 s qm | c q1 c qk | l q
| |
t 1 t m | u1 u k | r
Fiecare linie i dintre cele q ale matricei de informaţii se completează cu k
biţi de control, furnizaţi de către un cod liniar binar (m+k, m) care are
matricea generatoare Gm,m+k şi matricea de control Hk,m+k. În acest cod,
elementele si1, si2, ..., sim constituie partea de informaţii, iar elementele ci1,
ci2, ..., cik constituie partea de control a codului respectiv.
Ultima coloană a liniei i, cu elementele notate li, conţine biţii de paritate
longitudinală, astfel încât linia:
si1, si2, ..., sim, ci1, ci2, ..., cik, li
să aibă un număr par de cifre 1.
Cea de-a q+1 linie conţine biţii de paritate transversală. Astfel, fiecare
coloană j dintre primele m:
s1j, ..., s2j, ..., sqj, tj
conţine un număr par de cifre 1. De asemenea, fiecare din următoarele k coloane:
c1j, ..., c2j, ..., cqj, uj
conţine un număr par de cifre 1.
Deci ultima linie şi cu ultima coloană sunt completate astfel, încât să
formeze un cod iterativ. Prin teorema 3 am demonstrat că alegerea
elementului r de pe poziţia (q+1, m+k+1) verifică atât paritatea longitudinală
a liniei cât şi pe cea verticală a coloanei lui.
Teorema 2.4
Din următoarele patru ipoteze:
1. Hk,m+k este matricea de control a unui cod liniar binar;
2. pentru fiecare j de la 1 la q configuraţia de m+k biţi: si1, si2, ..., sim, ci1, ci2,
..., cik este cuvânt de cod, cu m biţi de informaţie şi k biţi de control;
3. biţii t1, ..., tm asigură parităţile transversale ale coloanelor biţilor de
informaţie sij;
29
4.biţii u1, ..., uk asigură parităţile transversale ale coloanelor biţilor de
informaţie cij;
Atunci, configuraţia t1, ..., tm, u1, ..., uk este un cuvânt de cod liniar binar
generat de matricea Gm+k,m şi acceptat de matricea de control Hk,m+k, cu biţii notaţi
tj reprezentând partea de informaţie, iar biţii notaţi uj partea de control.
i 1 i 1
Să considerăm, de exemplu, scrierea pe un suport magnetic a şirului de
caractere ASCII „ABCD”. Fiecare dintre cele patru caractere se vor
reprezenta pe câte 8 biţi. Aceste coduri ASCII, scrise în hexazecimal, sunt:
41 42 43 44
Drept cod liniar binar vom folosi codul (7, 4) dat ca exemplu în secţiunea 2.2.
Matricea de informaţie va avea q = 8 linii, câte una pentru fiecare bit al fiecărui
octet, deci fiecare octet este reprezentat pe o coloană. Fiind vorba de 4 octeţi,
matricea de informaţii va avea m = 4 coloane. Codul liniar binar (7, 4) va mai
adăuga şi el încă trei coloane pentru biţii lui de control, iar codul iterativ va mai
introduce încă o linie şi o coloană. Deci, blocul de informaţie va avea conţinutul:
0 0 0 0 | 0 0 0 | 0
1 1 1 1 | 1 1 1 | 1
0 0 0 0 | 0 0 0 | 0
0 0 0 0 | 0 0 0 | 0
0 0 0 0 | 0 0 0 | 0
0 0 0 1 | 1 1 1 | 0
0 1 1 0 | 0 1 1 | 0
1 0 1 0 | 1 0 1 | 0
| |
0 0 1 0 | 1 1 0 | 1
30
2.2.4 Codul lui Hamming
Codul lui Hamming este un cod autocorector bazat pe teste de paritate.
Versiunea cea mai simplă permite corectarea unui bit eronat. Celor m biţi de
informaţie li se adaugă k biţi de control al parităţii. Vom avea n = m+k biţi
necesari pentru transmiterea informaţiei.
Deoarece trebuie indicate n + 1 posibilităţi de eroare (inclusiv absenţa
erorii) prin cei k biţi de control, trebuie ca 2k n + 1. Cele 2k posibilităţi de
de codificare pe k biţi servesc la determinarea poziţiei erorii, apoi se poate
corecta bitul eronat.
Tabelul următor permite determinarea lui k când se cunoaşte n:
m 0 0 1 1 2 3 4 4 5 6 7 8 9 10 ... 120
k 1 2 2 3 3 3 3 4 4 4 4 4 4 4 ... 8
n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ... 128
De obicei se ia n 2k – 1 în loc de n < 2k – 1.
Dacă se numerotează biţii de la dreapta spre stânga pornind de la 1, biţii
de control (sau de paritate) sunt plasaţi pe poziţia puterilor lui 2 (biţii cu
numărul 1, 2, 4, 8, 16, ...). Fiecare bit de control efectuează control de
paritate (pară sau impară) asupra unui anumit număr de biţi de date. Se
determină astfel cei n biţi de transmis sau de stocat.
Exemplu: Dacă m 4 se poate construi un cod Hamming (CH) pe 7 biţi
(n 7), adăugând 3 biţi de control (k 3).
7 6 5 4 3 2 1
m4 m3 m2 k3 m1 k2 k1
Cei trei biţi de control sunt plasaţi pe poziţia puterilor lui 2:
k1 1; k2 2; k3 4.
Vom vedea acum, pentru fiecare bit al mesajului care sunt biţii de control
care permit verificarea parităţii sale.
7 (0111)2 4 + 2 + 1 7 este controlat de k3, k2, k1;
6 (0110)2 4 + 2 6 este controlat de k3, k2;
5 (0101)2 4 +1 5 este controlat de k3, k1;
4 (0100)2 4 4 este controlat de k3;
3 (0011)2 2+1 3 este controlat de k2, k1;
2 (0010)2 2 2 este controlat de k2;
1 (0001)2 1 1 este controlat de k1;
Problema se pune şi invers: care sunt poziţiile binare controlate de către
fiecare cod? Răspunsul este următorul:
k1 controlează biţii cu numerele 1, 3, 5, 7;
k2 controlează biţii cu numerele 2, 3, 6, 7;
k3 controlează biţii cu numerele 4, 5, 6, 7.
31
Când se recepţionează informaţia, se efectuează controlul de paritate.
Pentru fiecare bit de control se compară valoarea transmisă cu cea recalculată.
Dacă cele două valori sunt identice, se atribuie valoarea 0 unei variabile binare
Ai asociată bitului de control ki, altfel, Ai primeşte valoarea 1.
Valoarea zecimală a configuraţiei binare formată din variabilele Ak, Ak-1, ..., A1
furnizează poziţia bitului eronat, care se poate corecta.
Reluăm exemplul precedent:
Presupunem că: pentru k1, A1 1, pentru k2, A2 1, iar pentru k3, A3 0.
Eroarea se găseşte în poziţia (A3A2A1)2 (011)2 3.
Într-adevăr, k1 poate detecta o eroare în poziţiile 1, 3, 5, 7, k2 poate
detecta o eroare pe poziţiile 2, 3, 6, 7, iar k3 pe poziţiile 4, 5, 6, 7. O eroare
detectată de k 1 şi k 2 nu şi de k3 nu poate proveni decât din bitul 3.
Exemple:
(A3A2A1)2 (000)2 indică absenţa unei erori;
(A3A2A1)2 (001)2 indică eroare pe bitul 1;
(A3A2A1)2 (110)2 indică eroare pe bitul 6.
Exemplu de recepţionare a unui mesaj: (1011100)2. Dacă s-a utilizat un
CH cu paritate pară, să se reconstituie mesajul iniţial (n 7, k 3, m 4).
număr 7 6 5 4 3 2 1
tip m4 m3 m2 k3 m1 k2 k1
valoare 1 0 1 1 1 0 0
k1 0 controlează poziţiile 1, 3, 5, 7, nu se verifică, deci A1 1;
k2 0 controlează poziţiile 2, 3, 6, 7, se verifică, deci A2 0;
k3 0 controlează poziţiile 4, 5, 6, 7, nu se verifică, deci A3 1;
Adresa erorii (A3A2A1)2 (101)2 5. Bitul numărul 5, care este egal cu 1
este eronat. Mesajul iniţial corectat şi fără biţii de control este: (1001)2.
32
Biţii cu valoarea 1 se găsesc pe poziţiile 15, 13, 11, 9, 7, 3, deci:
15 1 1 1 1
13 1 1 0 1
11 1 0 1 1
91 0 0 1
70 1 1 1
30 0 1 1
-----------
0 1 0 0 biţi de paritate
k4 k3 k2 k1
Mesajul codificat este deci (101010101001100)2.
Exemplu de recepţie a unui mesaj:
S-a primit mesajul următor: (101000101001100)2, codificat cu paritate
impară. Biţii cu valoarea 1 se găsesc pe poziţiile 15, 13, 9, 7, 4, 3.
15 1 1 1 1
13 1 1 0 1
91 0 0 1
70 1 1 1
40 1 0 0
30 0 1 1
---------- adunare modulo 2 inversată.
0 1 0 0
A4A3A2A1 eroare pe poziţia 4.
După corectarea erorii şi eliminarea codurilor de control, mesajul iniţial
este: (10100011001)2.
33
11 10 9 8 7 6 5 4 3 2 1 (număr)
H 1001000 1 0 0 1 1 0 0 1 0 0 0
a 1100001 1 1 0 0 0 0 0 0 1 1 0
m 1101101 1 1 0 0 1 1 0 0 1 1 1
m 1101101 1 1 0 0 1 1 0 0 1 1 1
i 1101001 1 1 0 0 1 0 0 1 1 0 1
n 1101110 1 1 0 0 1 1 1 1 0 0 1
g 1100111 1 1 0 0 0 1 1 0 1 0 1
34
2) Se efectuează împărţirea modulo 2: M(x)*xr/G(x)Q(x)+R(x)/G(x);
Câtul Q (x) se ignoră, iar restul R (x) conţine r biţi.
3) Se efectuează scăderea modulo 2: M (x) * xr – R (x) T (x), iar T (x)
este polinomul care reprezintă mesajul de transmis. Polinomul ciclic
T (x) Q (x) * G (x) este un multiplu al polinomului generator.
4) La recepţionarea mesajului se efectuează împărţirea T (x) /G (x):
a) dacă restul 0 nu sunt erori de transmisie;
b) altfel, s-au produs erori, deci mesajul trebuie retransmis.
Exemplu de transmitere a unui mesaj. Se doreşte transmiterea mesajului
101101 (6 biţi) M (x) =x5 + x3 + x2 + 1.
Polinomul generator este: 1011 G (x) = x3 + x + 1 de grad r = 3.
1) Efectuăm înmulţirea: M (x) xr = 101101000 (se adaugă r = 3 zerouri
la M (x).
2) Realizăm împărţirea modulo 2: M (x)*xr/G (x):
1 0 1 1 0 1 0 0 0 1 0 1 1
1011 ---------
-------- 1 0 0 0 0 1 câtul Q(x)
000001000
1011
--------
0 0 1 1 R (x) = 0 1 1
3) Câtul Q (x) este ignorat. Pentru a realiza diferenţa modulo 2, M (x)
*xr – R (x) este suficientă adăugarea celor r biţi din R (x) la sfârşitul
mesajului M (x) mesajul de transmis este T (x) = 101101011.
Exemplu de recepţionare a unui mesaj. S-a primit mesajul următor:
11010101. G (x) = 1011 (4 biţi) G (x) = x3 + x + 1 de grad r = 3.
4) Se efectuează împărţirea T (x) / G (x).
1 1 0 1 0 1 0 1 1 0 1 1
1011 ---------
-------- 11110
01100
1010
--------
01111
1011
--------
01000
1011
--------
0 0 1 1 1 R (x) = 1 1 1
35
R (x) 0, s-au detectat erori de transmisie, mesajul se retransmite.
Cele mai utilizate polinoame generatoare G (x) sunt:
CRC – 12 x12 + x11 + x3 + x2 + x + 1;
CRC – 16 x16+ x15 + x2 + 1;
CRC – CCITT x16 + x12 + x5+ 1.
and 0 1 or 0 1 not
0 0 0 0 0 1 0 1
1 0 1 1 1 1 1 1
Funcţii booleene
„Semnificaţia” unei expresii logice poate fi descrisă formal ca o funcţie
care dă o valoare adevărat sau fals pentru expresia întreagă pornind de la
valoarea argumentelor, numită funcţie logică sau booleană.
36
Tabele de adevăr
O funcţie booleană poate fi reprezentată în practică printr-o tabelă de
adevăr ale cărei linii corespund tuturor combinaţiilor de valori de adevăr
pentru argumente. Există o coloană pentru fiecare argument şi una pentru
valoarea funcţiei.
Figura următoare prezintă tabelele de adevăr pentru operaţiile logice
and, or, not, xor.
p q p and q p q p or q p not p p q p xor q
0 0 0 0 0 0 0 1 0 0 1
0 1 0 0 1 1 1 0 0 1 0
1 0 0 1 0 1 1 0 0
1 1 1 1 1 1 1 1 1
Notaţii prescurtate
and se reprezintă prin juxtapunerea operanzilor;
37
or se reprezintă prin +;
not se reprezintă prin sau prin bararea variabilei.
38
18. Subsumarea:
a) p p q p ;
b) p p q p .
19. Eliminarea anumitor negaţii:
a) p p q p q ;
b) p p q p q .
20. Legile lui de Morgan:
a) p q p q ;
b) p q pq ;
c) p1 p2 ... pn p 1+ p 2+...+ p n;
d) p1 p2 ... pn p1 p2 ... pn .
1) Funcţii de o variabilă a:
a z0 z1 z2 z3 z0 = 0 constantă;
0 0 0 1 1 z1 = a identitate;
1 0 1 0 1 z2 = a negaţie;
z3 = 1 constantă;
39
0 0 0 0 F0 = 0
0 0 0 1 F1 = a b
0 0 1 0 F2 = a b
0 0 1 1 F3 = a
0 1 0 0 F4 = a b
0 1 0 1 F5 = b
0 1 1 0 F6 = a b
0 1 1 1 F7 = a b
1 0 0 0 F8 = a b a b
1 0 0 1 F9 = a b
1 0 1 0 F10 = b
1 0 1 1 F11 = a b
1 1 0 0 F12 = a
1 1 0 1 F13 = a b
1 1 1 0 F14 = a b a b
1 1 1 1 F15 = 1
40
De observat cercul de la ieşirea porţii NOT. Cercul reprezintă operaţia de
complementare. O altă poartă este poarta sau-exclusiv (XOR), reprezentată de
expresia booleană xy. XOR este falsă când valorile de intrare sunt egale şi
adevărată altfel. Figura următoare ilustrează tabela de adevăr pentru XOR,
precum şi diagrama logică care îi specifică comportamentul.
Porţi universale
Alte două porţi sunt NAND şi NOR, care produc outputul complementar
pentru AND şi OR. Fiecare poartă are două simboluri logice diferite care pot fi
folosite pentru reprezentare. Figura următoare ilustrează diagramele logice pentru
NAND şi NOR şi tabelele de adevăr pentru a explica comportamentul funcţional
al fiecărei porţi.
41
De ce să nu folosim porţile AND, OR şi NOT pe care le cunoaştem? Există
două motive pentru folosirea doar a porţilor NAND la construirea oricărui circuit.
Primul: porţile NAND sunt mai ieftin de construit decât celelalte. În al doilea
rând, circuitele integrate complexe sunt adesea mult mai uşor de construit
folosind aceleaşi elemente (de exemplu, câteva porţi NAND) decât o colecţie de
elemente de bază (de exemplu, o combinaţie de porţi AND, OR şi NOT).
De asemenea, se poate construi un circuit folosind numai porţi NOR.
Deoarece porţile NAND şi NOR sunt legate în general în acelaşi fel ca o
sumă de produse logice şi, respectiv, un produs de sume logice, se poate
folosi NAND pentru implementarea unei expresii în forma sumă de produse
şi NOR pentru expresii în forma produs de sume.
TK cu 2 variabile
Cele 4 căsuţe ale TK corespund celor 4 linii ale tabelei de adevăr:
fiecare variabilă logică completează o linie sau o coloană;
un produs de 2 variabile completează o căsuţă;
42
Pentru a completa TK pornind de la tabela de adevăr se atribuie valoarea
1 căsuţelor corespunzătoare stărilor din intrare în care funcţia are valoarea 1.
Metoda de simplificare constă din a încadra căsuţele ocupate, adiacente pe
aceeaşi linie sau coloană (suprapunerile parţiale sunt permise). Figura
următoare prezintă o TK cu 2 variabile.
a
a b z b 0 1
0 0 0 0 1
0 1 1
1 0 1 1 1 1
1 1 1
În urma reducerii avem vom obţine z = a+b.
TK cu 3 variabile
Tabela de adevăr a funcţiei logice de 3 variabile se transformă într-o TK
cu două dimensiuni, grupând două variabile pe linie sau coloană. Trecerea
de la o linie (coloană) la alta diferă printr-o singură variabilă (se consideră
tabela ca înfăşurătoarea unui cilindru.
Pentru construirea TK cu 3 variabile:
fiecare variabilă completează un bloc de 4 căsuţe;
un produs logic de două variabile completează un bloc de 2 căsuţe;
un produs logic de 3 variabile completează o căsuţă.
Exemplu: f (a, b, c) = a b c ab c ab c abc ;
b ac 00 01 11 10
0 1 1 1
1 1
TK cu 4 variabile
Se construieşte TK, precum înfăşurătoarea unui cilindru, atât orizontal
cât şi vertical, astfel:
fiecare variabilă completează un bloc de 8 căsuţe;
un produs logic de 2 variabile completează un bloc de 4 căsuţe;
un produs logic de 3 variabile completează un bloc de 2 căsuţe;
un produs logic de 4 variabile completează o căsuţă.
Exemplu:
43
z (a, b, c, d ) a b c d a b c d a b cd a bc d
abc d ab c d ab c d a bcd ab cd a bcd abcd
cd ab 00 01 11 10
00 1 1
01 1 1 1 1
11 1 1 1 1
10 1
2.4 Memorii
Ierarhia memoriilor
Figura următoare prezintă tipurile de memorie şi arată ierarhia existentă
între diferitele nivele de memorie.
44
Registre
CPU
memoria cache
memoria centrală
memoria de sprijin
memorii auxiliare
45
servesc ca dispozitive de stocare permanentă şi utilizează pentru
aceasta suporturi magnetice (discuri, cartuşe, benzi) şi suporturi optice
(discuri optice) spre deosebire de nivelele mai apropiate de CPU care
fac apel la tehnologia semiconductoarelor.
Organizarea informaţiilor
Informaţiile pe care le prelucrează un sistem de calcul trebuie să se
adapteze unui anumit format, ale cărui caracteristici generale sunt următoarele:
a) Bitul, constituie unitatea de bază a informaţiei. Într-o memorie, cel
mai mic element de stocare este numit adesea punct de memorie: el
memorează un bit de informaţie.
b) Octetul, mai cunoscut sub termenul englez de byte, corespunde unei
succesiuni de 8 biţi.
c) Caracterul este o grupare de 6, 7, 8, ... biţi, permiţând codificarea
unui caracter alfanumeric sau a unui caracter special (!, , $, %, ^, &,
*, “, , , ...) potrivit convenţiilor de codificare: ASCII, EBCDIC etc.
d) Cuvântul word este o grupare de biţi constituind unitatea de
informaţie adresabilă în memoria centrală şi care variază de la un
sistem de calcul la altul. Valorile 32 şi 64 au tendinţa de a deveni
valori generale pentru lungimea unui cuvânt.
e) Înregistrarea record semnifică un bloc de date şi constituie
unitatea de informaţie stocată în memoria auxiliară a sistemului de
calcul (disc, bandă).
f) Fişierul file este o mulţime finită de înregistrări.
Caracterisicile memoriilor
a) Adresa este valoarea numerică desemnând un element fizic de
memorie (de exemplu adresa unui cuvânt în memoria centrală).
b) Capacitatea unei memorii corespunde numărului de instrucţiuni pe
care le poate conţine şi se poate exprima în funcţie de numărul de
biţi, octeţi sau cuvinte.
c) Timpul de acces este timpul în care se realizează o operaţie de
acces (citire sau scriere).
d) Ciclul de memorie este timpul minimal între două accese succesive
la memorie. Acesta este mai lung decât timpul de acces deoarece
cuprinde şi anumite operaţii de întreţinere, sincronizare, stabilizare
de semnale în circuite etc.
e) Volatilitatea caracterizează permanenţa informaţiilor într-o
memorie. O memorie volatilă îşi pierde conţinutul la producerea
unei întreruperi de curent, deci are nevoie de o alimentare constantă
46
cu energie electrică pentru a-şi conserva informaţiile. Memoria
centrală pe semiconductoare este volatilă spre deosebire de
memoriile magnetice auxiliare.
f) Debitul este numărul de informaţii citite sau scrise pe secundă.
47
pentru a genera semnalele corespunzătoare către UAL pentru declanşarea
execuţiei instrucţiunii. Datele de prelucrat vor fi de asemenea căutate în
memorie de către unitatea de control şi transferate direct unităţii de calcul.
Diferitele unităţi ale sistemului de calcul sunt interconectate prin sisteme de
cablare care transportă semnale electrice. Pentru a se evita legarea unei unităţi
cu toate celelalte, se utilizează linii exploatate în comun de către toate unităţile
sistemului de calcul. Se numeşte bus, ansamblul de linii capabile de a transmite
semnale corespunzătoare celor trei tipuri de informaţii: adrese, date şi comenzi.
Există la ora actuală arhitecturi bazate pe bus unic, pe care sunt conectate
toate organele sistemului de calcul. O asemenea structură, specifică
microcalculatoarelor, este ilustrată în figura următoare:
MEMORIE CPU
BUS
Adrese Date Comenzi
INTRĂRI IEŞIRI
Unitatea de comandă
Unitatea de comandă este mulţimea tuturor dispozitivelor de coordonare
a funcţionării sistemului de calcul în vederea executării secvenţei de operaţii
specificate prin instrucţiunile programului.
Principalele dispozitive ale unităţii de comandă care vizează căutarea în
memorie şi decodificarea unei instrucţiuni (ciclul de căutare), sunt:
a) contorul ordinal (CO), este un registru care conţine adresa din
memorie unde este stocată instrucţiunea de căutat;
b) registrul instrucţiune (RI), primeşte instrucţiunea de executat;
c) decodificatorul codului operaţiei, care determină ce operaţie trebuie
să fie efectuată, dintre toate cele posibile;
d) secvenţatorul, care generează semnale de comandă;
e) ceasul intern, sau orologiul, care emite impulsuri electrice
uniforme, sincronizând astfel toate acţiunile unităţii centrale.
48
Circulaţia informaţiilor în timpul unui ciclu de căutare fetch cycle:
2
RA Memorie RC
CO RI
Decodificator
5
4
Orologiu Secvenţator
49
Secvenţa exactă a acţiunilor coordonate de către secvenţator va depinde
de tipul operaţiei; în general, în timpul unui ciclu de execuţie, informaţia va
circula potrivit schemei următoare:
2
RA Memorie RC
Unitate de UAL
comandă 1
Acumulator
Secvenţator 3
Nivele de programare
Pentru a scrie un program, utilizatorul poate utiliza unul dintre limbajele
de programare cunoscute: Fortran, Pascal, Ada, Asamblor etc. Sistemul de
calcul nu poate înţelege decât propriul său limbaj, limbajul maşină, cu
mulţimea sa de instrucţiuni.
În programare, se utilizează termenul limbaj pentru a indica o mulţime de
instrucţiuni şi de reguli sintactice care permit scrierea codului sursă al
programului. Deoarece sistemul de calcul execută doar programe scrise în cod
maşină sau cod obiect, apare necesitatea traducerii codului sursă în cod obiect,
care se realizează automat cu ajutorul compilatoarelor şi asambloarelor.
50
Limbajele de programare se poate prezenta pe mai multe nivele, cele
superioare fiind mai apropiate de limbajul utilizatorului, iar cele inferioare
fiind mai bine adaptate caracteristicilor sistemului de calcul. Situaţia actuală
este sintetizată în figura următoare:
limbaje evoluate
nivel asamblor
instrucţiuni maşină
micro-instrucţiuni
nivelul comenzilor
electronice
52
8. LOAD G Stiva = B; C + D E; F; G
9. DIV Stiva = B; C + D E; F / G
10. SUB Stiva = B; C + D E – F / G
11. MPY Stiva = B (C + D E – F / G)
12. STA A Stiva =
Setul instrucţiunilor
Fiecare tip de sistem de calcul posedă un set de instrucţiuni de bază, care
variază de obicei între 50 şi 250. La ora actuală există două mari tendinţe în
ceea ce priveşte setul de instrucţiuni de bază:
a) Arhitecturile RISC Reduced Instruction Set Computer
preconizează un număr mic de instrucţiuni elementare într-un format
fix, uşor de realizat din punct de vedere material (hardware) şi cu o
execuţie rapidă, ceea ce implică un secvenţator cablat şi un
compilator capabil să exploateze bine caracteristicile sistemului (de
exemplu, utilizarea pe o scară largă a registrelor şi limitarea
acceselor la memoria centrală);
b) Arhitecturile CISC Complex Instruction Set Computer sunt
bazate pe un set bogat de instrucţiuni, de talie variabilă, oferind
astfel instrucţiuni compuse, ca de exemplu, calculul rădăcinii pătrate
sau înmulţire în virgulă mobilă dublă precizie. În general aceste
sisteme sunt prevăzute cu secvenţator multiprogramat.
Instrucţiunile care pot face parte din setul de instrucţiuni de bază ale
oricărui sistem de calcul pot fi clasate în şase grupe, astfel:
a) transfer de date (Load, Move, Store, transfer de date între două
registre sau între memoria principală şi un registru);
b) operaţii aritmetice (cele patru operaţii în virgulă fixă sau mobilă, în
simplă sau multiplă precizie);
c) operaţii logice (AND, OR, NOT, XOR etc.);
d) control de secvenţă (salturi condiţionate şi necondiţionate, apel de
subprograme etc.);
e) intrări/ieşiri (Read, Write, Print etc.);
f) operaţii diverse ( decalări, conversii de format, incrementări de
registre etc.).
Registrele CPU
Numărul şi tipul registrelor pe care le posedă CPU constituie o
caracteristică determinantă a arhitecturii sale şi au o influenţă importantă
asupra programării.
53
Deşi structura registrelor CPU diferă de la un constructor la altul, totuşi,
funcţiunile de bază realizate prin diverse registre CPU sunt în general
aceleaşi. În continuare vom descrie principalele registre CPU:
a) Contorul ordinal (CO) PC=Program Counter conţine adresa de
memorie a următoarei instrucţiuni de executat. El este incrementat
automat de către sistem după fiecare utilizare (programatorul nu are
acces direct la CO). Programul este executat în secvenţă, cu excepţia
situaţiilor în care conţine o instrucţiune de modificare a secvenţei
(de exemplu, o instrucţiune de salt sau de ramificare), caz în care
noua adresă va înlocui conţinutul contorului ordinal.
b) Acumulatorul (Rac) este un registru foarte important al UAL, care,
în majoritatea operaţiilor aritmetice şi logice conţine unul dintre
operanzi înainte de execuţie şi rezultatul după execuţie. Registrul
acumulator poate fi de asemenea utilizat ca un registru tampon în
operaţiile de intrare/ieşire. În general Rac are aceeaşi talie ca şi un
cuvânt-memorie, dar cele mai multe sisteme de calcul admit
extinderea registrului acumulator (registrul Q) pentru a conţine
rezultatul unei înmulţiri, câtul şi restul unei împărţiri, sau poate
conţine biţii cei mai puţin semnificativi în cadrul unei operaţii în
virgulă mobilă dublă precizie;
c) Registrele generale general purpose register permit salvarea
informaţiilor utilizate în mod frecvent de către program sau a
rezultatelor intermediare, ceea ce conduce la accelerarea execuţiei
programului prin reducerea numărului de accese la memoria
centrală;
d) Registrele de index sau de indice (XR) index register se pot
utiliza ca registre generale pentru salvări şi contorizări, posedând în
plus o funcţie specială, de mare utilitate în manipularea tablourilor
de date. Registrele de index pot fi utilizate pentru manipularea
adreselor corespunzător unei forme particulare de adresare numită
adresare indexată;
e) Registrele de bază (Rb) base registers sunt utilizate ca registre de
index pentru calculul adreselor efective (adresare bazată) şi în
acest sens ele sunt concepute să conţină o adresă de referinţă care
trebuie adăugată la conţinutul câmpului de adresă al instrucţiunii
pentru a obţine adresa efectivă;
f) Registrul de stare PSW = Program Status Word, numit de
asemenea registru condiţie, conţine anumiţi biţi care indică starea
unei condiţii particulare în CPU. De exemplu, bitul indicator Z indică
dacă rezultatul operaţiei efectuate este egal cu zero, bitul indicator C
54
indică o depăşire de capacitate în Rac etc. Aceşti biţi pot fi testaţi prin
program pentru determinarea secvenţei de instrucţiuni de urmat;
g) Registrul pointer de stivă SP = Stack Pointer este utilizat pentru
a simula o stivă în memoria centrală. Registrul SP funcţionează ca
un registru de adresă de memorie (RA) şi conţine în orice moment
adresa corespunzătoare vârfului stivei, deci, când se încarcă un
cuvânt în stivă adresa sa se înscrie în SP, iar citirea din stivă se face
pornind de la adresa indicată de pointerul SP;
h) Registrele specializate sunt specifice anumitor sisteme de calcul şi
sunt destinate operaţiilor particulare, de exemplu, registre de
decalare shift registers, registre pentru operaţii aritmetice în
virgulă mobilă floating point registers etc.
Adresarea operanzilor
Câmpul de adresă al unei instrucţiuni nu conţine de fiecare dată adresa
efectivă a unui operand şi de aceea, pentru facilitarea activităţii de
programare sunt puse la dispoziţie mai multe metode de adresare a
operanzilor, cunoscute sub numele de moduri de adresare, specificate în
formatul instrucţiunilor printr-un bit care indică modul folosit.
Printre modurile de adresare, cele mai importante sunt:
a) adresare directă: câmpul de adresă al instrucţiunii conţine adresa
efectivă a operandului;
b) adresare indirectă: câmpul de adresă al instrucţiunii conţine adresa
la care găseşte adresa efectivă a operandului (pot exista mai multe
nivele de indirectare);
c) adresare imediată: câmpul de adresă al instrucţiunii conţine chiar
operandul;
d) adresare implicită: codul operaţiei indică locul unde se găseşte
operandul (de exemplu, maşini pe zero adrese);
e) adresare indexată: adresa efectivă = conţinutul câmpului de adresă
al instrucţiunii + conţinutul registrului de index;
f) adresare bazată: adresa efectivă = conţinutul câmpului de adresă al
instrucţiunii + conţinutul registrului de bază;
g) adresare relativă: asemănătoare adresării bazate, dar utilizează
conţinutul registrului CO ca adresă de bază.
Exemple de adresare
Pentru simplificarea scrierii, în exemplele următoare vom utiliza simboluri ca:
a, b, c, alfa etc. pentru a indica anumite date şi prescurtări precum: IM (adresare
imediată), I (adresare indirectă), XR1 (registrul de index nr. 1), B1 (registrul de
55
bază nr. 1). Ne propunem să arătăm care este efectul pe care-l au asupra
conţinutului registrului acumulator diferitele moduri de adresare utilizate.
Conţinutul memoriei şi al câtorva registre este prezentat în tabela următoare:
56
c) ADR > n: ADR poate adresa poziţii de memorie care nu există în
memoria fizică, ceea ce oferă posibilitatea extinderii memoriei
principale spre memoriile auxiliare, de exemplu, discuri magnetice
(noţiunea de memorie virtuală).
57
magnetice, discuri şi dischete magnetice, discuri optice, ecrane video, mouse-
uri, creioane optice, cititoare optice de caractere sau de coduri specializate.
Tehnica ieşirilor a fost de asemenea considerabil dezvoltată. S-a trecut
astfel de la lămpile intermitente ale anilor ‘50, la ecranele color şi
imprimantele laser ale sistemelor contemporane.
Terminale interactive
Un terminal interactiv este un echipament periferic permiţând
utilizatorului o comunicare în ambele sensuri cu sistemul de calcul. Unitatea
de intrare este un dispozitiv interactiv precum tastatura keyboard sau
mouse-ul, iar unitatea de ieşire este un ecran de vizualizare display bazat
de obicei pe tehnica tubului catodic CRT.
Tastatura este dispozitivul interactiv prin excelenţă pentru toate
aspectele referitoare la tratarea unui text. Pentru o manipulare mai uşoară a
obiectelor pe ecran se utilizează mouse-ul.
Tastatura unui sistem de calcul este asemănătoare cu cea a unei maşini de
scris care realizează imprimarea pe o foaie de hârtie a caracterelor în urma
apăsării tastelor.
Prin acţionarea unei taste este lansat un semnal electronic care este
codificat în mod specific de exemplu în cod ASCII, iar caracterul
corespunzător tastei este afişat pe ecranul sistemului de calcul.
Ecrane alfanumerice
Un ecran alfanumeric se limitează la afişarea caracterelor distribuite pe un
anumit număr de linii, fiecare linie fiind compusă din mai multe sute de puncte.
Fiecare caracter este format dintr-o configuraţie de puncte alese conform
unei anumite grile, generând astfel o matrice de puncte.
Ecranul conţine în general o pagină de text organizată în 24 de linii şi 80
de coloane.
Ecrane grafice
Ecranele grafice permit atât afişarea caracterelor cât şi afişare de
imagini sau desene.
Prin apariţia şi dezvoltarea interfeţelor utilizatori - ecrane grafice bazate
pe folosirea ferestrelor şi pictogramelor, ecranele grafice au înlocuit ecranele
alfanumerice. Cele mai cunoscute ecrane grafice sunt:
a) Ecrane cu baleiaj TV la care ecranul este divizat în mici domenii
elementare (pixeli) care formează un număr de linii şi de coloane.
Evoluţia ecranelor cu baleiaj a cunoscut următoarele etape:
58
ecranele monocrome, care afişează imagini binare (bitmap),
unde fiecare element este reprezentat printr-un bit;
ecranele cu nivele de gri, care pot afişa imagini pixmap, în
care fiecare element de imagine poate avea un anumit nivel de
gri (8 biţi pot reprezenta 256 nivele de gri);
ecranele color, permit afişarea imaginilor în culori, dar pentru
aceasta sunt necesare memorii-imagine mai mari, deoarece
pentru fiecare element de imagine trebuie indicate valorile
celor trei culori de bază (bleu, verde şi roşu).
b) Ecrane vectoriale, care realizează vizualizarea prin adresarea
punctuală a ecranului în locul unui baleiaj sistematic. Se utilizează
un fascicol ca “stilou” pentru trasare curbe conform unui parcurs
definit printr-o secvenţă de comenzi stocate într-o memorie locală.
Ecranele grafice sunt adaptate aplicaţiilor unde domină liniile,
structurile filiforme, desenele prin trasaj (contur), fără o eficienţă
deosebită în reproducerea imaginilor pline (fotografii);
c) Ecrane plate. Miniaturizarea produselor electronice a antrenat
realizarea şi dezvoltarea afişajelor pe ecrane plate, mai mici şi mai
puţin fragile decât tuburile catodice. Tehnici, ca de exemplu,
cristalele lichide sau ecrane cu plasmă au devenit competitive.
Imprimante
Tehnicile de imprimare au evoluat considerabil, la ora actuală există o
mare varietate de imprimante, acoperind un interval extins de preţuri şi de
performanţe. Imprimarea poate fi alb-negru sau color, principalele
procedee de imprimare color fiind jetul de cerneală, transfer termic sau
sublimare termică.
Imprimantele color utilizează trei culori primare galben, cyan, magenta,
ca şi negru, ceea ce permite crearea unei vaste palete de culori.
Putem prezenta o variantă de clasificare a imprimantelor:
a) Imprimante cu impact, încă utilizate în administraţie datorită
posibilităţii de a realiza copii carbon:
teleimprimatoarele: capul mecanismului de imprimare are forma
unui cilindru pe care sunt gravate caracterele; între cilindru şi hârtia
de imprimat se găseşte o bandă îmbibată de cerneală;
imprimantele Boole: caracterele sunt înscrise pe o sferă;
imprimantele matriciale (prin puncte): caracterele sunt
compuse pornind de la punctele unei grile (matrice) de 7 9
sau 9 13, potrivit calităţii de imprimare alese;
59
b) Imprimantele fără impact, unde calitatea de imprimare este dată de
densitatea punctelor imprimate, care se exprimă în dpi dots per inch:
imprimante termice: se aseamănă cu imprimantele matriciale
dar în locul lovirii unei benzi, se realizează încălzirea unei
suprafeţe de hârtie specială, sensibilă la căldură. Funcţionarea
este silenţioasă, iar în ceea ce priveşte imprimarea termică
color, sunt cunoscute două tehnologii: transfer termic şi
sublimare termică, ambele utilizând un rulou de celofan
acoperit de o cerneală în stare solidă, compusă dintr-o
succesiune de regiuni de culoare galbenă, cyan, magenta;
imprimante cu jet de cerneală: sunt silenţioase şi au viteza de
imprimare comparabilă cu cea a imprimantelor termice, putând
imprima orice simbol sau grafism. Principiul de funcţionare
constă în crearea unui fascicol de picături de cerneală dirijate
asupra hârtiei cu o mare precizie. Calitatea de imprimare este
foarte bună, rezoluţia variază între 200 dpi şi 1200 dpi;
imprimante laser: utilizează metode şi procedee
electrostatice. Se formează o imagine electrostatică pe un
tambur fotoconductor, tamburul trece prin faţa staţiei de
dezvoltare unde cerneala încărcată electric este atrasă numai de
punctele precedent încărcate. Imaginea este transferată pe
hârtie prin frecarea acesteia pe tambur. Această tehnică nu
necesită hârtie de calitate superioară, rezoluţia variază între
300 şi 2000 dpi (standard 600 dpi).
Digitalizoare
Digitalizoarele scanners sunt echipamente periferice care permit
„numerizarea” unei imagini pornind de la o copie pe suport solid (hârtie).
Rezultatul digitalizării este o imagine digitală stocată într-un fişier.
60
În cazul legăturii directe între CPU şi periferic apare problema diferenţei
enorme între vitezele de lucru ale celor două dispozitive, CPU rămâne blocat
pe toată durata transferului de informaţie.
În vederea utilizării raţionale a CPU, se utilizează tehnica întreruperii
programului. Metoda constă în introducerea unui semnal numit întrerupere
interrupt trimis spre CPU de către perifericul gata să efectueze un schimb
elementar, de exemplu, transferul unui octet. Acest semnal provoacă
întreruperea programului în curs de execuţie, CPU se ocupă de transfer prin
activarea unui program special (program de serviciu de întrerupere), iar
după efectuarea transferului, CPU reia programul întrerupt.
Abordarea cea mai economică constă în suspendarea programului în
execuţie timp de un ciclu-memorie, fără un efect deosebit asupra timpului
de execuţie. Această metodă se materializează prin utilizarea canalelor de
intrare/ieşire sau acces direct la memorie DMA.
Sistemul de întreruperi
Întreruperea este un semnal electronic generat de către o unitate
funcţională, de exemplu, canal sau controler de periferice, şi acest semnal
este transmis spre CPU pentru a provoca o ruptură de secvenţă în vederea
execuţiei unui program prioritar, care tratează cauza întreruperii.
Sistemul de întrerupere, încorporat în CPU la nivelul secvenţatorului,
este dispozitivul care înregistrează semnalele de întrerupere trimise către
CPU, ale căror cauze pot fi:
a) interne în raport cu CPU, de exemplu: depăşire de capacitate
(overflow), coduri de operaţii inexistente, erori de adresare, utilizare
abuzivă a instrucţiunilor privilegiate, pană de curent.
b) externe în raport cu CPU, de exemplu: starea unei unităţi periferice,
sfârşitul unui transfer de date.
Tratarea unei întreruperi se realizează prin următoarele acţiuni:
a) oprirea execuţiei programului în curs;
b) salvarea stării sistemului;
c) executarea programului de serviciu de întrerupere;
d) restaurarea stării sistemului;
e) reluarea execuţiei programului întrerupt.
Diversele cauze ale întreruperilor sunt afişate într-un vector de
indicatori asociat sistemului de întrerupere, iar programul care tratează
întreruperea trebuie să testeze aceşti indicatori.
În sistemele evoluate, fiecare întrerupere are asociată o adresă în
memoria centrală, iar ruptura de secvenţă este realizată prin transferul în
contorul ordinal a adresei unde se găseşte programul de serviciu.
61
Majoritatea sistemelor de calcul moderne sunt prevăzute cu sisteme de
întrerupere ierarhizate priority interrupt systems, acestea fiind sistemele cu
nivele de prioritate.
Problemele care trebuiesc rezolvate sunt următoarele:
sosirea mai multor semnale de întrerupere în timpul execuţiei unei
instrucţiuni;
sosirea unui semnal de întrerupere în timpul execuţiei unui program
de prelucrare a unei întreruperi anterioare.
În aceste sisteme, fiecare nivel este asociat unui anumit număr de
întreruperi, fiecărui nivel îi corespunde un anumit nivel de prioritate, iar orice
program poate fi întrerupt în vederea realizării unei întreruperi mai prioritare.
Sistemele de întrerupere cele mai elaborate sunt cele care fac parte din
sistemele de calcul orientate către aplicaţii de conducere a proceselor
industriale process control sau de achiziţionare de date data acquisition.
Un sistem de întrerupere modern trebuie să permită programatorului
următoarele acţiuni:
invalidarea/activarea disable/enable sistemului de întrerupere;
mascarea/demascarea individuală a întreruperilor;
stabilirea unei ierarhii în mulţimea cauzelor intreruperilor şi
definirea mai multor nivele de prioritate, de preferinţă dinamic;
asocierea unui program specific fiecărei întreruperi, permiţând
acţiuni elementare realizabile într-o singură instrucţiune;
posibilitatea de utilizare a tuturor registrelor care caracterizează
starea maşinii şi refacerea acestora la sfârşitul programului de
întrerupere.
3 SUPERCALCULATOARE ŞI MICROPROCESOARE
3.1 Supercalculatoare
62
dinamica fluidelor, aerodinamică, analiza structurilor, microelectronică,
fizica particulelor, chimia moleculară, matematici aplicate, simularea
numerică a sistemelor, prelucrarea imaginilor etc.) necesită creşterea vitezei
de execuţie a unităţii centrale, sau distribuirea calculelor pe mai multe
procesoare care lucrează în paralel.
Dezvoltarea sistemelor de calcul vizează asigurarea creşterii
performanţelor şi miniaturizarea.
Supercalculatoarele supercomputers sunt acele sisteme de calcul cu
performanţe deosebite, destinate în special aplicaţiilor ştiinţifice şi tehnice
avansate, spre deosebire de modelele comune şi mai răspândite, în general
afectate aplicaţiilor care nu solicită calcule numerice foarte pronunţate.
La cealaltă extremitate a gamei de sisteme de calcul se situează
microcalculatoarele care au la bază microprocesoare, iar adiţional, pot să
conţină: coprocesoare matematice, memorii cache, funcţii diverse de
comunicare şi de intrare/ieşire.
Microcalculatoarele sunt fabricate în cantităţi mari şi oferă performanţe
deosebite şi la preţuri relative scăzute.
În contextul sistemelor de calcul, conceptul de paralelism semnifică
faptul că mai multe acţiuni se pot derula simultan, într-o manieră
concurenţială. De aceea, prin creşterea gradului de paralelism al maşinii de
calcul va creşte şi capacitatea sa de prelucrare, dar maşina devine mai
complexă şi mai dificil de programat. Deşi sistemele care conferă un grad
ridicat de paralelism sunt doar rareori exploatate într-un procentaj maxim,
totuşi majoritatea aplicaţiilor pot profita, chiar şi într-o mai mică măsură de
arhitectura paralelă a sistemului.
63
execuţie pe un sistem VAX11/780), obţinându-se un SPEC_ratio pentru
fiecare program, iar media aritmetică a tuturor acestor valori se exprimă
printr-un SPEC_mark.
Pentru procesoare se utilizează următoarele unităţi de măsură standard:
- MIPS: milioane instrucţiuni pe secundă;
- FLOPS: caracterizează reprezentarea în virgulă mobilă a
informaţiilor. Se utilizează MFLOPS (MegaFlops), GFLOPS
(GigaFlops), TFLOPS (TeraFlops);
- SPEC.
Aceste măsurători furnizează indicatori mai mult teoretici, alegerea unui
sistem de calcul se face în realitate în funcţie de gradul de satisfacere al
necesităţilor aplicaţiilor destinate.
Exemple de supercalculatoare
Se pot distinge două categorii de supercalculatoare:
- supercalculatoare vectoriale: procesorul este capabil să lucreze
asupra vectorilor de date;
- supercalculatoare multiprocesoare.
Cei mai reprezentativi constructori de supercalculatoare vectoriale sunt:
Cray în SUA, Fujitsu, Hitachi şi Nec în Japonia.
Primul supercalculator vectorial a fost Cray-1 (monoprocesor de 10
MIPS şi 160 MFLOPS) realizat în 1976 de Seymour Cray. În 1980 s-au
comercializat Cray-XMP şi Cray-2 având până la patru procesoare, fiecare
procesor fiind capabil de câte 25 MIPS şi 450 MFLOPS. Cray-3 şi seria
YMP confirmă tendinţa către microprocesoare, memorii centrale de mare
capacitate. La concurenţă cu Cray, NEC produce SX-3, care depăşeşte 25
GFLOPS cu cele patru procesoare ale sale.
Maşinile paralele care reprezintă singura direcţie de cercetare care
propune atingerea TFLOPS (mii de miliarde de operaţii în virgulă mobilă pe
secundă) sunt reprezentate de constructorii americani (TMC Thinking
Machine Corporation, Intel, Cray, IBM), japonezi (Fujitsu) şi cei europeni
(Kendall Square Research, Meiko, Telmat, ACRI, Archipel). De exemplu,
compania TMC lanseză CM-200 având 4000-64000 procesoare de 1 bit şi
CM-5 având 32-8000 procesoare pe 32 sau biţi.
Pipeling
Pipeling este tehnica care permite efectuarea mai multor activităţi în unitatea
de timp, atunci când trebuie repetată o operaţie asupra unui număr mare de
operanzi, prin segmentarea operaţiei complexe într-o secvenţă de acţiuni mai
simple, fiecare acţiune simplă fiind realizată de către un dispozitiv particular.
64
În acest context, în loc să fie concepută o unitate S, capabilă să efectueze
operaţia P într-un interval de timp T, se va diviza operaţia P în segmentele
P1, P2, P3, …, executate de către subunităţile S1, S2, S3, … în intervalele de
timp T1, T2, T3, …, fracţiuni ale timpului T.
Când lanţul pipeline este complet încărcat (plin), adică toate
subunităţile sunt ocupate, începe furnizarea rezultatelor într-un ritm mult mai
ridicat decât în cazul unei unităţi nesegmentate.
Prin utilizarea acestei tehnici nu creşte viteza de execuţie a unei operaţii,
doar se produc mai multe rezultate pe secundă, furnizând în mod continuu
operanzi la intrare pentru pipeling.
De axemplu, în cazul unei adunări în virgulă flotantă se poate segmenta
operaţia în cinci părţi corespunzând unui număr de cinci staţii de lucru,
afectate operaţiilor următoare:
- compararea exponenţilor;
- interschimbarea mantiselor (dacă este cazul);
- decalarea mantiselor;
- adunarea mantiselor;
- normalizarea rezultatului.
După cum se vede şi în figura următoare (A, B, C, D, E şi F sunt operaţii
de efectuat iar RA, RB, RC, RD, RE, RF, rezultatele acestor operaţii), debitul
rezultatelor este cam de n ori mai mare în cazul unei unităţi operaţionale
divizate în n părţi decât pentru o unitate nesegmentată.
FEDCBA S1 S2 S3 S4 S5 RFRERDRCRB RA
Secţiuni de
pipeling Rezultate RA RB RC RD RE RF
S5 A B C D E F
S4 A B C D E F
S3 A B C D E F
S2 A B C D E F
S1 A B C D E F
1 2 3 4 5 6 7 8 9 10 11 Timp
Tehnica pipeling se poate aplica şi altor dispozitive în afara celor de
calcul. De exemplu, secţiunea unităţii de comandă care tratează
instrucţiunile poate fi organizată în pipeling, segmentând ciclul de căutare şi
ciclul de execuţie a instrucţiunii într-o secvenţă de acţiuni, care se pot
reacoperi în timp, după cum urmează:
65
- căutarea în memoria centrală a instrucţiunii următoare;
- decodificarea codului operaţiei;
- căutarea operandului;
- activarea secvenţatorului;
- efectuarea operaţiei;
- incrementarea registrului CO cu o unitate.
Maşini paralele
Progresul tehnologic permite astăzi realizarea unor arhitecturi cu un
foarte înalt nivel de paralelism, cu sute sau chiar mii de procesoare. Aceste
maşini sunt supercalculatoarele care, pentru anumite aplicaţii pot să ofere
posibilităţi de atingere a unor performanţe remarcabile.
Ideea care stă la baza oricărui calculator paralel este distribuirea
activităţilor necesare rezolvării unei probleme pe mai multe procesoare
făcând parte din aceeaşi maşină, deoarece majoritatea programelor se
rulează, de obicei în secvenţă, existând blocuri de instrucţiuni toatal
independente care ar putea fi executate simultan.
66
Aceasta presupune un nou stil de programare şi o complexitate deosebită la
nivel software. În acest context, anumite probleme, cum sunt cele din
matematicile aplicate, prelucrarea imaginilor sau fizică posedă un bun nivel de
paralelism natural şi pot fi adaptate uşor la prelucrarea paralelă.
În concluzie, există la ora actuală suficiente instrumente diferite şi destul
de complementare destinate rezolvării unor probleme complexe:
- maşini scalare puternice care execută instrucţiunile în secvenţă
potrivit principiilor lui von Neumann (în ultimii 45-50 de ani);
- procesoare vectoriale foarte puternice, capabile să rezolve
probleme dificil sau chiar imposibil de rezolvat cu procesoarele
scalare (în ultimii 20-25 de ani);
- maşini paralele cu enorma capacităţi de calcul distribuite pe un
număr mare de procesoare (în ultimii 10-15 ani).
3.2 Paralelism
67
tratează o singură secvenţă de instrucţiuni Single Instruction
stream şi o singură unitate de execuţie (UAL) care tratează o
singură secvenţă de date Single Data tream;
- SIMD Single Instruction Multiple Data streams: sunt maşini
care posedă o unitate de comandă unică dar mai multe unităţi
de execuţie. Toate procesoarele execută aceeaşi instrucţiune
simultan. În această categorie se pot clasa procesoarele
vectoriale care execută aceeaşi instrucţiune asupra tablourilor
de elemente;
- MIMD Multiple Instructions Multiple Data streams: se pot
clasa în acestă categorie multiprocesoarele, unde fiecare
procesor execută un program diferit şi de asemenea, maşinile
paralele în care toate procesoarele lucrează asupra unei singure
probleme;
- MISD Multiple Instructions Single Data stream: s-a prevăzut
o asemenea rhitectură din motive de simetrie, dar nu s-a
realizat nici-un exemplar din aceasta categorie.
Se poate remarca faptul că majoritatea tehnicilor care vizează creşterea
performanţelor (de exemplu: pipeling, antememorie etc.) nu se adresează în
mod direct unui utilizator concret (paralelism transparent).
Există de asemenea paralelism vizibil, care necesită colaborarea
utilizatorului (de exemplu: maşini vectoriale şi paralele).
3.3 Microprocesoare
68
- memoria, care poate fi de tip RAM, pentru înregistrarea datelor,
rezultatelor intermediare şi finale sau de tip ROM, unde sunt
înregistrate instrucţiuni, constante, rutine de bibliotecă etc.;
- intrările/ieşirile care conţin registre tampon şi circuite de interfaţă
care permit unităţilor periferice să comunice cu sistemul;
- bus-ul de date permite transferul informaţiilor în cele două sensuri.
Într-un microcalculator pe 8, 16, 32, 64, 128 biţi bus-ul va avea 8,
16, 32, 64, 128 linii;
- bus-ul de adrese este unidirecţional, el procesorul pentru adresarea
memoriilor şi a registrelor tampon de interfaţă cu perifericele
(exemplu: un bus de adrese cu 16 linii poate transporta 2 16 = 65536
adrese diferite);
- bus-ul de comenzi transportă semnalele utilizate pentru a
sincroniza diversele activităţi care se desfăşoară în unitatea
funcţională a microcalculatorului (exemplu: semnale se ceas intern,
semnale de citire, semnale de scriere, semnale de întrerupere etc.).
69
operare simplu, bazat pe o interfaţă de tip text şi a cărui utilizare solicită
cunoaşterea unui limbaj informatic specific.
La sfârşitul anilor ’80 a apărut un nou sistem de operare, Windows,
bazat pe o interfaţă utilizator-grafică mult mai prietenoasă, similară cu cea a
calculatoarelor Macintosh ale firmei Apple.
Interfaţa utilizator-grafică GUI: Graphical User Interface utilizează
ferestre, meniuri, pictograme şi privilegiază utilizarea mouse-ului.
În timp ce staţiile de lucru au o „vocaţie” mai ştiinţifică, calculatoarele
Macintash şi PC se adresează publicului larg.
Tendinţa actuală în domeniul microcalculatoarelor este aceea de realizare a
maşinilor multimedia, care oferă posibilitatea prelucrării unor tipuri diferite
de informaţii (de exemplu: date, sunet, imagini fixe sau animate).
Cei mai reprezentativi constructori de pe piaţa staţiilor de lucru sunt: Sun
Microsystems, IBM, HP, DEC.
Cu un sistem de operare bazat pe UNIX, adesea conectate în reţea în
configuraţii numite clusteri de staţii de lucru, aceste staţii de lucru pot
realiza capacităţi de calcul mari şi pot fi utilizate în paralel, de o manieră
asemănătoare supercalculatoarelor, dar la un preţ mult mai atrăgător.
Calculatoarele portabile care manifestă la ora actuală o adevărată
expansiune sunt caracterizate prin dimensiuni reduse, greutate de câteva
kilograme, autonomie de funcţionare de câteva ore şi pot fi echipate cu hard-
discuri, ecrane color, fax, imprimante miniaturale etc.
În domeniul calculatoarelor portabile există două tendinţe:
- calculatoare cu tastatură notebook care sunt microcalculatoare
clasice care beneficiază de noile tehnologii în privinţa ecranului (de
exemplu: cristale lichide etc.);
- calculatoare fără tastatură block-notes sau notepads, care
posedă un ecran tactil asupra căruia se poate scrie cu un creion
special şi un program de recunoaştere a caracterelor scrise.
4 ELEMENTE DE TELEINFORMATICĂ
70
Reţelele de calculatoare sunt constituite din elemente ale informaticii şi
ale sistemelor de telecomunicaţii.
Evoluţia teleinformaticii a cunoscut mai multe etape:
a) transmiterea datelor între două calculatoare (anii ‘60);
b) accesarea informaţiei la distanţă, deci o tendinţă de descentralizare
prin utilizarea staţiilor de intrare/ieşire (anii ‘70);
c) reţele de terminale (comutare de circuite cu concentratori,
multiplexare), reţele de calculatoare (comutare mesaje, pachete)
(sfârşitul anilor ‘70);
d) teleinformatica cu utilizarea pe scară largă a reţelelor publice, locale,
comunicaţie între reţele prin tehnica sateliţilor, utilizarea fibrelor
optice ca suport fizic, comunicaţia digitală etc. (anii ‘80 şi în prezent).
În general, o reţea poate fi definită ca o mulţime de noduri legate printr-
un ansamblu de drumuri (deci poate fi reprezentată printr-un graf).
Topologia reţelei vizează localizarea nodurilor şi modul lor de înlănţuire.
În mod obişnuit se utilizează un număr de reţele, ca de exemplu: şosele, căi
ferate, linii aeriene, poşta, telefon, electricitate, apă, radio, televiziune etc.
Noţiunea de reţea nu este un concept nou şi exemplele anterioare permit
evidenţierea unor caracteristici generale ale reţelelor:
a) serviciul oferit prin reţea depinde de tipul legăturii folosite în reţea.
De exemplu, şoselele furnizează o reţea punct la punct, în timp ce
apa este difuzată în toate nodurile reţelei;
b) utilizarea unei reţele în bune condiţiuni implică respectarea unui
anumit număr de reguli. De exemplu, pe şosele se poate circula
respectând regulile de circulaţie;
c) o reţea se poate construi pe alte reţele. De exemplu, poşta utilizează
şosele, căi ferate, linii aeriene.
O reţea teleinformatică (o vom numi, fără riscul confuziei, reţea) este o
reţea ale cărei noduri sunt constituite din unităţi de prelucrare a informaţiei,
schimbul de informaţie realizându-se prin intermediul legăturilor dintre
noduri, numite canale de transmisie.
În practică, nodurile pot fi calculatoare sau echipamente terminale (ecran
de vizualizare + tastatură + imprimantă) şi canalele de transmisie sunt adesea
linii telefonice pentru marile reţele şi cabluri coaxiale pentru reţelele locale.
Pentru schimbul de informaţie, două unităţi de prelucrare trebuie să
respecte aceleaşi protocoale, care sunt reguli complexe de comunicare.
4.1 Transmisia informaţiilor
71
a) cale metalică: este o linie electrică ce poate fi o linie telefonică sau
un cablu electric. Această soluţie prezintă unele inconveniente care
se referă la sensibilitatea la zgomote, scăderea semnalului transmis
la distanţă etc;
b) fascicol hertzian: utilizează unde radioelectrice pentru transportul
informaţiei;
c) fibre optice: transportul informaţiei este realizat prin propagarea
undelor luminoase în fibre de sticlă, prezenţa sau absenţa unui
semnal luminos permiţând codificarea unui bit de informaţie.
Utilizarea acestor diverse suporturi de informaţie poate fi schematizată
astfel: o legătură intercontinentală este realizată cu ajutorul unui satelit, o
legătură între calculatoarele unei ţări se realizează prin linii telefonice, o
legătură între două clădiri din acelaşi oraş se face prin fibre optice, legătura
între diverse echipamente din aceeşi clădire utilizează cablu coaxial, iar dacă
echipamentele sunt apropiate, se foloseşte un simplu cablu electric.
72
receptor se realizează în timpul transmiterii fiecărui caracter.
Datorită transmisiei aleatoare a caracterelor, acestea sunt încadrate
de biţi suplimentari pentru asigurarea corectitudinii transmisiei
(start-bit, stop-bit, bit de paritate). Acest mod de transmisie este
relativ simplu şi ieftin, dar redondanţa datorată biţilor adăugaţi nu
permite realizarea unei mari capacităţi de transmisie şi utilizarea sa
este limitată la terminale lente ca tastatura sau imprimanta;
b) transmisia sincronă: biţii sunt emişi în mod regulat, fără separare între
caractere. Pentru sincronizare se utilizează un ceas-bit atât de către
emiţător cât şi de către receptor. Sincronizarea caracterelor se realizează
prin recunoaşterea secvenţelor particulare de biţi. Acest mod de transmisie
permite debite mai mari de informaţie (superioare de 12000 biţi/sec).
Banda de trecere
O cale de transmisie nu permite decât transportul semnalelor care aparţin
unui anumit domeniu (bandă) de frecvenţe. Banda de frecvenţe corect
transmisă este numită bandă de trecere (notată W), şi constituie
caracteristica esenţială care determină direct capacitatea de transmisie.
H. Nyquist a arătat că rapiditatea de semnalizare (capacitatea de
transmisie) a unei căi este C = 2*W bound, unde W este mărimea benzii de
trecere. Bound-ul este unitatea de rapiditate a semnalizării şi corespunde
unui anumit număr de semnale pe secundă, iar dacă fiecare semnal permite
transmiterea a n biţi, atunci C = 2*n*W biţi/sec (bps).
În anul 1948, C. Shannon a arătat că rapiditatea de semnalizare este
determinată nu numai de banda de trecere ci şi de raportul semnal (S) /
bruiaj (B), şi anume: C = W * log2 (1 + S / B) (Hz).
Transmisie analogică şi digitală
a) transmisia analogică: constă în a utiliza un semnal simplu numit
undă purtătoare căreia i se modifică unul sau mai mulţi parametri:
amplitudine, frecvenţă, fază;
73
b) modularea: constă în transformarea informaţiilor digitale în
informaţii analogice prin modelarea unei unde purtătoare
sinusoidală periodică ce se poate reprezenta s (t) =A*sin (*t+),
sau s(t)=A*sin (2**f*t+) unde: A este amplitudinea semnalului,
este pulsaţia, f este frecvenţa, iar este faza inţială. Există trei
posibilităţi de modulare a semnalului:
modulare în amplitudine: s (t) = A (t) * sin ( * t + );
modulare în frecvenţă: s (t) = A * sin (2 * * f (t) * t+);
modulare de fază: s (t) = A * sin (2 * * f * t + (t)).
Multiplexare
Multiplexarea înseamnă partajarea unei căi de transmisie între mai multe
legături. O legătură este stabilirea unei comunicaţii între două echipamente
informatice. Sunt utilizate în principal două tehnici:
a) multiplexare frecvenţială FDM: Frequency Division
Multiplexing (spaţială) care constă în divizarea benzii de trecere a
căii de transmisie, semnalele sub-benzilor de trecere sunt adăugate
unele altora pentru a fi transmise pe calea de transmisie cu ajutorul
multiplexorului, iar la recepţie un demultiplexor filtrează semnalul
primit. Semnalele transmise astfel sunt analogice, pentru semnalele
numerice trebuie utilizat un modem pentru modularea acestora;
b) multiplexarea temporală: TDM: Time Division Multiplexing
constă în partajarea în timp a căii de transmisie între mai multe
transmisii, tehnică ce se poate utiliza şi pentru transmisii digitale.
Multiplexoarele inteligente ITDM: Intelligent TDM sau statistice
rezolvă problema alocării tranşelor de timp potrivit necesităţilor
fiecărei legături (mod asincron) (se mai numesc concentratoare).
74
3.2 Reţele de calculatoare
75
transmit în continuare mesajul la un nod apropiat, într-o bună direcţie.
Aceasta este o reţea punct la punct.
O altă tehnică de transmisie la distanţă utilizează o reţea de difuziune
broadcasting, care difuzează direct informaţia către toţi membrii reţelei.
Mesajul este întotdeauna etichetat cu o adresă pe care numai destinatarul o
recunoaşte. Acest tip de reţea necesită în mod normal utilizarea unui satelit
pentru transmisia informaţiilor.
76
Reţea de tip plasă Reţea de tip stea Reţea de tip arbore
77
Topologiile cele mai utilizate pentru reţelele locale sunt cele de tip bus şi inel.
Reţelele locale funcţionează în general prin difuziune, adică o staţie ce
doreşte să transmită un mesaj îl expediază în reţea, staţia vizată prin mesaj
recunoaşte adresa sa şi în consecinţă ea tratează acest mesaj, în timp ce alte
staţii, nerecunoscând mesajul, îl ignoră.
Protocoale de reţea
Un protocol de reţea este constituit din mulţimea regulilor care trebuie
să fie respectate pentru a realiza un schimb de informaţii între sistemele de
calcul din cadrul reţelei.
O modalitate de simplificare a problemei comunicării în reţea este
aceea de divizare a acesteia prin definirea mai multor nivele de comunicare
şi stabilind un protocol pentru fiecare nivel.
Problema standardizării presupune definirea de norme pentru
simplificarea comunicaţiilor în reţelele eterogene.
În timp ce constructorii au tendinţa de a defini propriile lor protocoale,
totuşi, un anumit număr de instituţii şi organizaţii internaţionale încearcă să
definească standarde, şi anume:
departamentul apărării americane DOD a definit protocolul
TCP/IP pentru reţeaua Arpanet;
instituţiile internaţionale:
- CCITT Comité Consultatif International du Téléphone et du
Télégraphe a definit recomandări reunite sub denumirea de seria
V (transmisia datelor prin telefon) şi seria X (reţele publice);
- ISO International Standards Organization cu modelul OSI
Open Systems Interconnection;
78
a) Nivelul 1 (fizic) este cel mai de jos nivel şi descrie caracteristicile
electrice şi echipamentul fizic de transmisie (cabluri, fascicole
hertziene etc.). El se ocupă de conexiunea fizică a staţiei la reţea,
permite transmisia de biţi între două sisteme, defineşte dacă
transmisia este sincronă sau asincronă, rezolvă probleme de
modulare/demodulare ale informaţiilor.
b) Nivelul al 2-lea (legătură de date, sau linie) data link are drept
scop transmisia datelor structurate în pachete de biţi fără erori (în
caz de eroare se procedează la retransmisia acestora).
c) Nivelul al 3-lea (reţea) serveşte în principal asigurării comutaţiei şi
rutării pachetelor de date între nodurile reţelei, de asemenea
efectuează controlul fluxului informaţiilor.
d) Nivelul al 4-lea (transport) permite stabilirea, întreţinerea şi
întreruperea conexiunilor de transport. Se efectuează controlul
fluxului informaţiilor şi se asigură segmentarea şi reasamblarea
mesajelor, precum şi multiplexarea căilor de tramsmisie.
e) Nivelul al 5-lea (sesiune) permite stabilirea unei conexiuni logice
între două aplicaţii, asigură organizarea şi sincronizarea dialogului,
modul de transmisie: simplex, semiduplex, duplex.
f) Nivelul al 6-lea (prezentare) se ocupă de aspectele prezentării
(sintaxa) datelor, conversia codului, formatul datelor, optimizarea
transferului prin diverse metode de comprimare şi asigurarea
securităţii datelor prin criptare.
g) Nivelul al 7-lea (aplicaţie) furnizează servicii şi interfeţe de
comunicaţie ale utilizatorului, deci constituie mulţimea punctelor de
intrare în programele utilizatorilor.
79
Conexiuni inter-reţele: internet şi TCP/IP
Pentru a încerca rezolvarea conexiunii între diferite reţele a apărut
noţiunea de internetwork sau general referită internet. Internet defineşte o
mulţime de protocoale independente de reţea. O versiune UNIX a acestor
protocoale a fost dezvoltată în ultima perioadă şi a avut ca efect conexiunea
unui mare număr de universităţi, firme şi persoane fizice.
Un anumit număr de aplicaţii sunt bazate pe protocoale TCP/IP de înalt
nivel şi pot fi considerate ca servicii universale:
poşta electronică;
transfer de fişiere la distanţă;
emularea unui terminal la distanţă;
gestiunea automată a reţelelor.
Adresarea staţiilor într-o reţea internet se realizează printr-o adresă pe 32
biţi descompusă în două părţi (identificatorul reţelei şi identificatorul local al
staţiei) şi reprezentată în general prin patru numere de câte 8 biţi.
80
particularităţilor de implementare a reţelelor specifice fiecărei ţări.
Această reţea oferă servicii deosebite:
servicii suport de informaţii (transmisie date + servicii
telefonice);
servicii complementare (identificare apel, sub-adresare
terminale, portabilitate etc);
teleservicii (transmisii de fişiere cu imagini fixe sau animate,
videofonia, videoconferinţa etc);
b) Evoluţia comutaţiei prin pachete vizează următoarele aspecte esenţiale:
creşterea performanţelor prin sporirea debitului şi simplificarea
protocoalelor de reţea;
posibilitatea transmisiei izocrone (vocea);
c) Releu de cadre frame relay: este o simplificare a transmisiei prin
pachete. În acest caz se utilizează acelaşi protocol de rutare, dar se
suprimă protocoalele de control a erorilor şi a fluxului (nivelul reţea
este vid). Această abordare este de 4-10 ori mai rapidă decât
comutaţia prin pachete şi se dovedeşte bine adaptată pentru
interconexiunea reţelelor locale.
d) Releu de celule cell relay are drept principiu descompunerea
informaţiilor în mici pachete de lungime fixă şi determinarea rutei
acestora. Comutaţia prin circuite permite transportul informaţiilor
izocrone (vocea), în timp ce comutaţia prin pachete este mai
adaptată transmisiei informaţiilor numerice. Releul de celule
realizează deci un compromis între cele două moduri de comutaţie.
e) RNIS cu bandă largă: permite transportul tuturor tipurilor de informaţii
(de exemplu, imaginile de televiziune). Spre deosebire de RNIS prima
versiune, care nu solicită modificarea cablajului abonaţilor, RNIS cu
bandă largă cere modificări multiple în reţeaua de transport şi va utiliza în
acest sens tehnica sateliţilor şi fibrele optice, mod de transfer asincron
potrivit tehnicii ATM Asynchronous Transfer Mode.
f) Reţele locale fără fir CLAN: Cordless LAN: nu necesită cablare, se
utilizează doar în cazuri particulare datorită tehnologiei foarte costisitoare.
Transmisia se realizează prin unde radio sau prin infraroşu.
g) Reţele de foarte înalt debit: dezvoltă viteze de transfer de ordinul
gigabiţilor pe secundă prin utilizarea fibrelor optice. Încă nu s-au definit
protocoale standard ci doar particulare care realizează conexiuni punct la
punct şi care necesită echipamente specifice foarte perfecţionate.
5 ELABORAREA PROGRAMELOR
81
Tehnologia produselor software software engineering caracterizează
mulţimea tuturor metodelor şi instrumentelor care permit elaborarea
produselor software.
Dezvoltarea unei mari aplicaţii este o problemă complexă care nu constă
numai în a programa, în sensul strict al cuvântului, aceasta presupune
parcurgerea unui anumit număr de etape, ceea ce constituie ciclul de viaţă
al unui produs software.
În plus, un mare proiect este dezvoltat de către echipe de programatori,
ceea ce obligă la descompunerea problemei în subprobleme pentru fi
repartizate între echipe, asigurarea comunicaţiei corespunzătoare între
echipe, controlul evoluţiei proiectului şi a calităţii produsului software.
Ciclul de viaţă se compune din fazele următoare:
a) Analiza şi formularea clară a problemei: constă în a stabili
funcţionalităţile, restricţiile şi obiectivele proiectului în acord cu
clientul/utilizatorul. Principala problemă a acestei faze rezidă în
comunicarea dintre conceptor şi client.
b) Specificarea: constă în determinarea funcţionalităţilor detaliate ale
produsului software ce urmează a fi realizat, fără o preocupare
deosebită pentru modalitatea de implementare efectivă.
c) Concepţia: este faza de definire a structurii modulare a produsului
software, alegerea algoritmilor corespunzători precum şi a
limbajelor de programare adecvate.
d) Programarea constă în implementarea efectivă a diferitelor module
care compun produsul software.
e) Testarea şi validarea: constă în depistarea erorilor de concepţie şi
de programare încât să se poată oferi asigurarea că produsul
software răspunde bine exigenţelor formulate iniţial.
f) Întreţinerea: este faza cea mai îndelungată a ciclului de viaţă a unui
produs software, care durează toată perioada de exploatare a
produsului. În timpul acestei faze se încearcă să se răspundă
cerinţelor utilizatorilor, fie corectând erorile apărute, fie efectuând
modificări, fie adăugând noi funcţionalităţi.
g) Documentarea: constă în regruparea tuturor informaţiilor produse
în timpul ciclului de viaţă. Documentarea nu este deci o fază proprie
a ciclului de viaţă, dar ea trebuie să se efectueze în timpul fiecărei
faze în paralel cu derularea acesteia. Documentarea trebuie să
permită înţelegerea şi modificarea ulterioară a produsului software.
Trecerea de la o fază a ciclului de viaţă la următoarea este rareori
definitivă, se întâmplă frecvent să se revină la o fază anterioară pentru a se
aduce un anumit număr de modificări. Într-adevăr, este foarte dificil să se
82
prevadă în avans toate aspectele şi în plus, în timpul fazei de întreţinere,
modificările importante cum ar fi crearea unei noi versiuni implică
dezvoltarea completă pornind de la faza de specificare. Din acest aspect
decurge noţiunea de ciclu.
Etapele ciclului de viaţă ale unui produs software sunt prezentate
schematic în figura următoare:
Analiza problemei
Specificare
Concepţie
Programare
Testare şi validare
Întreţinere
83
În mod obigatoriu, primele programe erau scrise în binar (limbajul
maşină), activitate dificilă şi expusă riscurilor de eroare, datorită secvenţelor
de biţi a căror semnificaţie era înscrisă într-o tabelă descriind toate operaţiile
posibile şi semnificaţia lor binară.
În continuare, pentru uşurarea activităţii de programare s-au elaborat
limbajele de asamblare.
Scrierea de programe în limbaj de asamblare rămâne o sarcină
complicată şi de asemenea programele depind de sistemul de calcul pe care
au fost concepute. Limbaje evoluate, ca de exemplu, Fortran sau Pascal au
adus o soluţie (parţială) acestor probleme.
Ca şi în cazul limbajelor de asamblare, programele scrise în limbajele de
programare evoluate trebuie să fie convertite în limbaj maşină pentru a fi
executate, iar conversia se poate efectua în două moduri diferite: traducere
sau interpretare.
Traducerea constă în a genera un program echivalent programului sursă,
dar codificat în limbajul binar al calculatorului. Traducerea este un procedeu
prin care, pornind de programul sursă, se generează un program obiect, care
se poate încărca ulterior în memorie pentru execuţie.
Interpretarea efectuează conversia şi execuţia unui program într-o
singură etapă: instrucţiunile sunt citite unele după altele şi sunt convertite
imediat în limbaj maşină prin intermediul interpretorului care realizează
execuţia lor pe măsura apariţiei. Totul se petrece ca şi când limbajul sursă ar
fi acceptat de către maşină.
Interpretarea este mai bine adaptată dezvoltării şi punerii la punct a
programelor deoarece execuţia începe imediat, iar traducerea este indicată
pentru exploatarea programelor, când nu mai este reluată traducerea.
Limbajele evoluate dispun în general de un traducător (compilator), dar
pot dispune şi de un intrerpretor (exemplul limbajului Pascal).
84
Spre deosebire de limbajele evoluate, limbajul de asamblare nu ascunde
nimic programatorului, permiţând accesarea tuturor resurselor sistemului şi
exploatarea facilităţilor de prelucrare ale acestuia.
O instrucţiune în limbaj de asamblare este divizată în mai multe câmpuri
care sunt separate în general prin spaţii. Numărul operanzilor din al zona de
adresă variază de la un sistem de calcul la altul între 0 şi 3. După acest câmp
este de dorit adăugarea comentariilor pentru documentare. Iată structura
tipică a unei instrucţiuni în limbaj de asamblare:
Operanzi şi etichete
Spre deosebire de limbajul maşină, limbajul de asamblare permite
atribuirea de nume pentru variabile şi etichete (adrese de instrucţiuni), ceea
ce uşurează programarea.
De asemenea, operanzii pot să posede un nume care permite referirea lor,
iar fiecare registru are un nume predefinit, recunoscut de către programul de
traducere.
Exemple de operanzi şi etichete:
Tab DS 1 Definirea unei variabile Tab de un cuvânt;
Zece DC 10 Definirea constantei Zece care are val. 10;
Ciclu: MOVE Zece, A1 Transferul valorii 10 în registrul A1;
MOVE A2,Tab Transfer valoare registru A2 în variabila Tab;
JUMP Ciclu Salt necondiţionat la adresa Ciclu.
Literale
Limbajul de asamblare permite definirea valorilor întregi sau reale în
diverse baze de numeraţie (2, 8, 10 sau 16) ca şiruri de caractere, care sunt
traduse de către asamblor. Specificarea bazei de numeraţie se face prin
plasarea unui caracter particular la începutul fiecărei date. Absenţa
caracterului particular specifică o dată zecimală. Şirurile de caractere sunt de
regulă delimitate de caracterul „ ‘ ”.
Directive
85
Directivele sau pseudo-instrucţiunile sunt instrucţiuni neexecutabile
(referite prin cod mnemonic) care nu au cod maşină echivalent. Acestea sunt
indicaţii pentru asamblor (traducător) în vederea traducerii programului.
Exemple de directive:
TTL ‘Titlul programului’
Vec DS 50 Definire variabilă Vec şi rezervare 50 cuvinte;
Zero DC 0 Definire constantă Zero cu valoare 0;
PLEN 50 50 linii pe pagină (PLEN=Page Length);
END Sfârşit de program.
Expresii aritmetice
Spre deosebire de limbajele evoluate, expresiile aritmetice utilizate
pentru a calcula valoarea unei variabile, ca de exemplu în atribuirea
următoare: A = B + C / D, nu sunt admise în limbajul de asamblare şi de
aceea trebuie programate prin mai multe instrucţiuni.
Macroinstrucţiuni şi subprograme
Anumite asambloare permit structurarea programelor, ele oferă în
general posibilitatea de a grupa o secvenţă de instrucţiuni sub forma unui
subprogram sau a unei macroinstrucţiuni, în scopul modularizării
programului şi a evitării scrierii repetate a unor grupuri de instrucţiuni.
Macroinstrucţiuni
O macroinstrucţiune se construieşte prin izolarea unei secvenţe de
instrucţiuni căreia i se atribuie un nume simbolic prin care poate fi referită.
Ori de câte ori în cadrul programului se face referire la acest nume,
asamblorul, în etapa de traducere, înlocuieşte referinţa cu secvenţa de
instrucţiuni corespunzătoare.
Utilizarea macroinstrucţiunilor prezintă mai multe avantaje, şi anume:
extinderea setului de instrucţiuni, deoarece fiecare macroinstrucţiune
se utilizează ca o altă instrucţiune;
reducerea şi structurarea programelor, care conduce la înţelegerea şi
modificarea uşoară a acestora;
economisirea timpului de programare.
Instrucţiunile care servesc pentru definirea şi delimitatea
macroinstrucţiunilor (de exemplu, MACRO şi ENDM) sunt cazuri tipice de
directive; în timpul asamblării, fiecare apel al unei macroinstrucţiuni este
înlocuit prin corpul macroinstrucţiunii şi cele două pseudo-instrucţiuni sunt
eliminate.
Exemplu: Calculul cubului unui număr:
86
MACRO CUB (val, valcub)
MOVE val, D1
MOVE val, D2
MUL D1, D2 (D2:= D1 D2)
MUL D1, D2
MOVE D2, valcub
ENDM
Subprograme
Subprogramele sunt definite ca şi macroinstrucţiunile, având de
asemenea scopul de a evita repetarea scrierii unei secvenţe de instrucţiuni ce
va fi utilizată de mai multe ori.
O diferenţă esenţială faţă de macroinstrucţiune rezidă în faptul că
instrucţiunile care compun subprogramul constituie o entitate bine separată
de programul principal, iar această separare se păstrează şi după traducere,
încât subprogramul se găseşte o singură dată în memorie şi doar la execuţia
programului se satisfac referinţele la un subprogram al său.
Această manieră de abordare a programării conduce la avantaje
suplimentare faţă de utilizarea macroinstrucţiunilor, deoarece permite
minimizarea taliei codului executabil, ceea ce nu este cazul
macroinstrucţiunilor.
Problemele care se manifestă în situaţia utilizării subprogramelor se
referă în special la asigurarea salvării adresei de revenire în timpul
execuţiei unui subprogram. Adresa de revenire este adresa instrucţiunii care
urmează după instrucţiunea de apel a subprogramului.
Deci, principala diferenţă între o macroinstrucţiune şi un subprogram
este aceea că apelurile la o macroinstrucţiune sunt înlocuite prin corpul
macroinstrucţiunii în timpul traducerii, pe când apelurile la un subprogram
sunt tratate în timpul execuţiei.
Transmiterea parametrilor
Un program poate să schimbe date cu macroinstrucţiunile şi
subprogramele sale prin intermediul parametrilor. Un parametru este o
variabilă al cărei nume este cunoscut, dar al cărei conţinut nu este precizat
decât în momentul execuţiei. O macroinstrucţiune sau un subprogram se
scrie utilizând parametrii formali care vor fi înlocuiţi prin parametrii
efectivi corespunzători datelor reale care sunt tratate.
Substituţia parametrilor formali cu cei efectivi se realizează la traducere,
pentru macroinstrucţiuni, şi la execuţie, pentru subprograme.
87
Pentru subprograme există mai multe tehnici de transmitere a
parametrilor:
a) Transmiterea prin valoare constă în recopierea valorii de transmis
într-o zonă cunoscută de subprogram, care poate fi o zonă de
memorie sau un registru. În acest fel, subprogramele acţionează
asupra unei copii a parametrilor, orice modificare a parametrului nu
este posibilă decât în interiorul subprogramului, iar la revenire în
programul apelant parametrul regăseşte valoarea sa iniţială, ceea ce
permite o anumită protecţie a parametrilor.
b) Transmiterea prin referinţă constă în a transmite către
subprogram adresele parametrilor. Subprogramul lucrează deci
efectiv asupra datelor programului apelant, deci orice modificare a
valorii parametrului în interiorul subprogramului este reflectată la
revenire în programul apelant.
Recursivitate
Un subprogram este recursiv dacă poate să se autoapeleze (direct sau
indirect).
Problema unui subprogram recursiv este că în timpul fiecărui apel,
trebuie salvată starea maşinii. Datorită faptului că nu se poate utiliza aceeaşi
zonă de memorie pentru salvare, se adoptă o soluţie bazată pe utilizarea unei
stive care lucrează după principiul LIFO Last In, First Out, în care se
salvează starea maşinii pe măsura activării apelurilor recursive (este
necesară o condiţie de sfârşit pentru apelurile recursive).
88
Figura următoare ilustrează diferenţa dintre o macroinstrucţiune şi un
subprogram.
salvare
stare
program
program
restaurare
stare
revenire
program
apel macroinstrucţiune
instrucţiune normală
apel subprogram
MACROINSTRUCŢIUNE SUBPROGRAM
89
Un limbaj informatic cuprinde:
un alfabet: mulţimea simbolurilor elementare disponibile;
nume sau identificatori: grupe de simboluri ale alfabetului (cu
anumite restricţii: număr de caractere, tipul primului caracter etc.);
fraze sau instrucţiuni: secvenţe de nume şi simboluri de punctuaţie
care respectă aspectele sintactice şi semantice ale limbajului.
Limbajele informatice, spre deosebire de limbajele naturale, sunt
structurate, riguros neambigue şi pot fi definite în mod formal.
Limbajele de asamblare au fost primele limbaje informatice şi ele depind
de arhitectura sistemelor de calcul.
Limbajele evoluate HLL: High Level Languages au apărut mai târziu şi
permit comunicarea cu sistemul de calcul fără a ţine seama de arhitectura sa.
În informatică se disting mai multe categorii de limbaje: limbajele de
programare şi limbajele de comandă sunt cele mai utilizate, dar există de
asemenea şi limbaje de analiză şi limbaje de specificare, care ajută în
timpul primelor faze de dezvoltare a produselor software.
Scrierea unui program se realizează prin utilizarea simbolurilor
limbajului de programare pentru constituirea frazelor sau instrucţiunilor care
trebuie să respecte sintaxa limbajului.
Cele două modalităţi de reprezentare a sintaxei unui limbaj sunt:
notaţia BNF Backus Naur Form;
diagramele sintactice.
Prezentăm în continuare un exemplu de sintaxă a unui limbaj foarte
simplu care permite definirea identificatorilor (încep întotdeauna cu o literă),
întregii fără semn, expresiile aritmetice simple şi instrucţiunea de atribuire.
Pentru notaţia BNF, semnul „ ” indică o alternativă, semnele „< ” şi
„ > ” delimitează obiectele limbajului şi semnul „ := ” indică atribuirea.
< literă > ::= a b c d . . .y z
< cifră > ::= 0 1 2 3 4 5 6 7 8 9
< identificator > ::= < literă > <identificator > < literă >
< identificator > < cifră >
< întreg > ::= < cifră > < întreg > < cifră >
< termen > ::= < întreg > < identificator >
< operator > ::= + - /
<expresie > ::= < termen >
<termen> < operator><expresie>
< atribuire > ::= < identificator > := < expresie >
90
literă
identificator literă
cifră
întreg cifră
întreg
termen
identificator
-
operator
expresie termen
operator
91
Concepte de bază ale limbajelor evoluate
Limbajele evoluate permit uşurarea activităţii de programare printr-o
apropiere de limbajul natural, dar cu respectarea exigenţelor de rigoare şi
neambiguitate.
Primele concepte de bază ale limbajelor de programare evoluate se
refereau la independenţa faţă de sistemul de calcul, ceea ce a permis
elaborarea unor instrucţiuni posedând un nivel semantic superior limbajului
de asamblare.
Elaborarea de limbaje de programare evoluate a vizat încă de la început
trei direcţii importante, şi s-a concretizat prin trei categorii de limbaje:
a) limbaje bazate pe conceptele de algoritm şi prelucrarea datelor cu
caracter ştiinţific (Fortran, Algol);
b) limbaje bazate pe prelucrarea datelor (Cobol);
c) limbaje bazate pe prelucrarea listelor (Lisp).
Limbajele din primele două categorii sunt limbaje procedurale care
furnizează o descriere detaliată a algoritmilor de rezolvare a problemelor, iar
limbajele din a treia categorie sunt limbaje funcţionale, care subliniază
aspectul funcţional al rezolvării unei probleme, fără a intra în detalii.
Orientarea algoritmică a permis în continuare dezvoltarea limbajelor Algol
60, Algol 68, Fortran II, Fortran IV, Fortran 66, Fortran 77, Fortran 90,
Pascal, C, Modula-2, Ada şi C++, care furnizează metodologii bazate pe
conceptele de programare structurată, abstractizare, modularitate etc.
A doua orientare, bazată pe prelucrarea datelor a rămas fidelă limbajului
Cobol, dar a evoluat spre sisteme de gestiune de baze de date care permit
rezolvarea problemelor specifice bazelor de date.
Limbajul Prolog, instrument de bază în domeniul inteligenţei artificiale, a
rezultat din abordarea funcţională şi aduce nou, în afară de prelucrarea listelor, un
mecanism de inferenţă foarte util pentru realizarea sistemelor expert.
Asistăm astăzi la o oarecare convergenţă între limbajele orientate
obiect şi bazele de cunoştinţe, ceea ce permite gruparea şi unificarea
conceptelor de bază ale diverselor orientări.
Vom prezenta în continuare o scurtă descriere pentru câteva limbaje de
programare dintre cele mai utilizate:
Fortran Formula Translator este primul limbaj algoritmic, utilizat în
principal pentru rezolvarea problemelor cu caracter ştiinţific. El produce
cod eficace, utilizează o mare cantitate de biblioteci matematice şi a
introdus concepte importante, ca de exemplu, structurarea expresiilor
aritmetice, subprograme, compilarea independentă a subprogramelor.
Limbajul a evoluat mereu, versiunea Fortran 90 permite programarea
paralelă şi concurentă specifică supercalculatoarelor.
92
Cobol Common Business Oriented Language este un limbaj destul de
utilizat în lume, şi este adaptat aplicaţiilor de gestiune care permit un acces
uşor la fişiere şi baze de date. Inconvenientele utilizării sale provin din
aspectul „stufos” al scrierii şi dificultatea de structurare a programelor.
Algol Algorithmic Oriented Language a avut o influenţă primordială
asupra limbajelor actuale. Definit pentru aplicaţii ştiinţifice, limbajul nu a
reuşit să se impună din cauza complexităţii sale, lipsei de soliditate a
intrărilor/ieşirilor şi lipsa eficacităţii. Totuşi, Algol a introdus conceptul
de structurare, cu structuri de blocuri, structuri de control, proceduri,
recursivitate. Este primul limbaj definit în notaţia BNF şi a evoluat în
Algol 60, Algol 68, Algol W dar a rămas în mediul academic.
Lisp List Processing a fost conceput pentru manipularea expresiilor şi
funcţiilor simbolice. Caracteristicile sale sunt: capacitatea de tratare a
listelor, un număr mic de operatori de bază, un număr mare de paranteze şi
recursivitatea care joacă un rol de seamă în parcurgerea listelor. Limbajul
este utilizat curent în inteligenţa artificială. Datorită lipsei de eficacitate pe
sisteme de calcul tradiţionale, anumiţi constructori au dezvoltat maşini
Lisp, care acceptă acest limbaj ca limbaj maşină, având o arhitectură
particulară, bazată pe noţiunea de stivă.
Basic Beginner’s All-purpose Symbolic Instruction Code este un
limbaj rudimentar, care a fost dezvoltat doar în scop didactic. El a
devenit un limbaj răspândit datorită dezvoltării microcalculatoarelor
care, la început nu aveau capacitatea de a utiliza alte limbaje.
PL/1 Programming Language number 1 este o realizare ambiţioasă,
un limbaj aproape universal, menit să înlocuiască limbajele Fortran,
Algol şi Cobol utilizate în acea epocă. Din cauza complexităţii sale,
lipsa de omogenitate şi de rigoare limbajul nu a cunoscut o mare
răspândire, limitându-se la calculatoarele din familia IBM.
Pascal, care poartă numele matematicianului francez creator al uneia
dintre primele maşini aritmetice de calcul din secolul XVII, a fost
dezvoltat de către elveţianul Niklaus Wirth. Acest limbaj provenit
din Algol căruia îi preia conceptele, este bazat pe o mare simplitate
şi este destinat înainte de toate învăţării programării.
Modula-2 este încă un limbaj dezvoltat de Wirth. Limbajul este un
descendent al limbajului Pascal, căruia îi adaugă noţiunea de
modularitate care permite compilarea independentă a modulelor.
Smalltalk este un limbaj care caracterizează o nouă tendinţă de
programare bazată pe conceptul de obiect. El permite o interacţiune
grafică cu sistemul, bazată pe utilizarea ferestrelor şi a meniurilor,
ceea ce constituie o inovaţie în domeniul programării.
93
Prolog Programmation Logique (elaborat în 1972 de către
Colmerauer) este un limbaj care preia conceptele limbajului Lisp,
adăugând un mecanism de inferenţă utilizat la realizarea sistemelor
expert. Japonezii şi-au pus mari speranţe în acest limbaj pentru
proiectul de sisteme de calcul de generaţia a cincea.
C, un succesor al limbajelor BCPL şi B, este un limbaj orientat spre
programare de sistem. Succesul limbajului se datorează utilizării
sale pentru dezvoltarea sistemului de operare UNIX. C este un
limbaj relativ simplu la nivel de concepte, codul generat de
compilator este eficace, dar sintaxa permite scrierea într-o linie a
instrucţiunilor foarte complexe, care devin aproape ilizibile.
Ada, al cărui nume aduce omagiu Adei Byron (sec. XIX),
considerată ca prima informaticiană, este un limbaj conceput pentru
departamentul apărării al SUA. El preia conceptele limbajelor
Pascal şi Modula-2, adăugând concepte de timp real, paralelism,
genericitate şi gestiunea excepţiilor.
C++ este un succesor al limbajului C, dezvoltat de către Bjarne
Stroustrup la începutul anilor ‘80. Acest limbaj,evoluţie naturală a
limbajului C, reia conceptele acestui limbaj, la care adaugă un anumit
număr de concepte legate de programarea orientată obiect, ca de
exemplu, noţiunea de clasă de obiecte, moştenire între clase etc.
Orientarea obiect
Evoluţia programării clasice se poate rezuma în felul următor:
a) Programarea procedurală procedural programming: accentul este
pus pe algoritmi, codul este repartizat în proceduri, iar structurile de date
nu sunt luate în considerare. Este cazul limbajelor Fortran sau C.
b) Încapsularea şi abstractizarea datelor data hidding and
abstraction: apare noţiunea de modul, care permite descompunerea
codului în diferite module. Datele sunt închise în interiorul
modulelor ceea ce constituie tipurile abstracte de date ADT:
Abstract Data Type. Practic, un ADT poate fi văzut ca o „cutie
neagră”, iar seviciile (metode) sunt oferite prin intermediul unei
interfeţe. Este cazul limbajelor Modula-2 şi Ada.
c) Programarea orientată obiect object oriented programming: reia
conceptele de tipuri abstracte de date dar se insistă asupra noţiunii
de reutilizare a obiectelor sistemului. În acest sens, se determină
principalele modele de date necesare, care se vor numi clase de
obiecte şi în continuare se stabilesc metodele care vor manipula
aceste modele. Un program se compune deci dintr-un ansamblu de
94
obiecte care interacţionează între ele trimiţându-şi mesaje care
activează metodele specifice fiecărei clase de obiecte. Este cazul
limbajelor Smalltalk, Eiffel, C++, Objective-C.
Clase şi obiecte
O clasă de obiecte corespunde implementării unui tip abstract de date.
Definiţia unei clase descrie comportamentul tipului său abstract prin specificarea
interfeţei tuturor operaţiilor (metode) aplicabile asupra tipului abstract.
Definiţia unei clase comportă de asemenea detalii cu privire la
implementarea unor astfel de structuri de date sau codul sursă care
implementează metodele.
Un obiect object este o variabilă a cărei tip este o clasă. El reprezintă o
instanţă (realizare) a unei clase. Acţiunile pot fi aplicate asupra acestui
obiect invocând metodele definite în clasă, care se realizează printr-un
procedeu numit trimitere de mesaje obiectelor clasei.
Clasele sunt entităţi definite în codul sursă al unui program, ele descriu
de o manieră statică o mulţime de obiecte (pot fi considerate şi ca tipuri de
date), în timp ce obiectele sunt elementele dinamice, ele nu există decât la
execuţie şi corespund instanţelor clasei.
Mesaje
Obiectele pot comunica între ele trimiţându-şi mesaje prin care se
solicită efectuarea unei anumite operaţii asupra acestor obiecte. Mulţimea
tipurilor de mesaje proprii unui obiect corespunde interfeţei sale.
Polimorfism
Polimorfismul permite efectuarea unei acţiuni prin trimiterea unui mesaj
la un obiect pentru care sunt posibile mai multe instanţe de execuţie. Această
capacitate este foarte importantă atunci când acelaşi mesaj poate fi îndeplinit
în moduri diferite pentru tipuri diferite de obiecte.
Limbajele orientate obiect permit trimiterea mesajelor identice spre
obiecte care aparţin unor clase diferite (dar derivate din clasa de bază).
Polimorfismul constă în esenţă în posibilitatea asocierii mai multor
implementări ale aceluiaşi mesaj, iar sistemul de calcul trebuie să fie în
măsură să stabilească implementarea corespunzătoare mesajului transmis.
95
Acestă decizie (constând în legarea mesajului de implementarea
corespunzătoare) se poate lua fie la compilare early sau static bilding, fie la
execuţie late sau dynamic bilding.
Genericitate
Genericitatea se exprimă prin capacitatea de a defini clase
parametrizabile. De exemplu, presupunem că este necesară o stivă de
numere întregi şi o stivă de numere reale. În locul definirii celor două tipuri
de stivă se va proceda la definirea unei clase parametrizată numită stivă, din
care se vor genera cele două clase dorite.
Genericitatea şi moştenirea corespund unor necesităti diferite şi
generează structuri diferite: moştenirea favorizează rafinamente succesive
ale unei aceeaşi clase rezultând astfel o structură pe verticală, în timp ce
genericitatea permite definirea unei clase de bază parametrizată care se poate
instanţia de mai multe ori cu tipuri diferite, rezultând astfel o structură pe
orizontală. Figura următoare evidenţiază această situaţie.
Moştenire Genericitate
(structură verticală) (structură orizontală)
96
Inteligenţa artificială şi sistemele expert
Inteligenţa artificială este domeniul informaticii care propune simularea
pe sistemele de calcul a comportamentului inteligent al omului. Sunt
implicate domeniile perceperii, înţelegerii, luării deciziilor, învăţării.
Această orientare a condus la unele rezultate notabile, în special în unele
domenii: teoria jocurilor, demonstrarea teoremelor, recunoaşterea formelor,
recunoaşterea parolelor, înţelegerea limbajelor naturale, rezolvarea
problemelor care necesită expertiză legată de un domeniu specific (de
exemplu, diagnosticul medical), matematici simbolice etc.
Inteligenţa artificială trebuie să permită rezolvarea problemelor pentru
care abordarea algoritmică este ineficientă sau chiar imposibil de aplicat. Un
program al inteligenţei artificiale se caracterizează prin utilizarea
simbolurilor în locul informaţiilor alfanumerice.
Sisteme expert
Sistemele expert constituie cu siguranţă domeniul inteligenţei artificiale
care a cunoscut cea mai mare dezvoltare. Un sistem expert este un program
care utilizează intensiv cunoştinţa în scopul rezolvării problemelor care
necesită în mod normal expertiza umană.
Într-un sistem expert există o separaţie netă între programe şi cunoştinţe.
Arhitectura de bază a unui sistem expert cuprinde trei părţi:
a) Baza de fapte este un fel de bază de date care regrupează faptele şi
aserţiunile vizând problema tratată;
b) Baza de reguli conţine cunoştinţele care permit manipularea
faptelor din baza de fapte. Cunoştinţele se exprimă sub formă de
reguli de producţie. O regulă comportă o parte stângă, exprimând o
condiţie (dacă) şi o parte dreaptă conţinând concluzii (atunci);
c) Motorul de inferenţă exploatează baza de cunoştinţe (baza de
fapte + baza de reguli) asociind faptele şi regulile pentru a formula
un raţionament asupra problemei puse. Pentru aceasta, pornind de la
baza de fapte, el determină mulţimea regulilor a căror parte stângă
este verificată, faptele conţinute în partea dreaptă adăgându-se la
baza de fapte. În continuare, motorul de inferenţă aplică aceste
reguli (înlănţuire înainte) pentru a ajunge la o concluzie, procesul
oprindu-se când nu se mai pot genera fapte noi. Se poate de
asemenea porni de la concluzie, inferenţele propagându-se invers
(înlănţuire înapoi). Ele determină noi subscopuri mai simplu de
verificat până la găsirea părţilor stângi ale regulilor corespunzătoare
faptelor din baza de fapte. Un anumit număr de limbaje (Lisp şi
Prolog) permit dezvoltarea cu uşurinţă a sistemelor expert simple.
97
4.3 Etapele dezvoltării unui program
Editor de texte
program sursă
Traducător asamblor
compilator
program obiect
subprograme subprograme
de bibliotecă traduse separat
Editor de legături
program obiect
Încărcător
program executabil
execuţie
Corector
98
Elementele clasice ale unui mediu de programare sunt următoarele:
editorul de texte, traducătorul (compilator sau asamblor), editorul de
legături, programul încărcător şi programul corector.
Editorul de texte
Editorul de texte text editor este un program interactiv care permite
preluarea unui text pornind de la tastatură şi stocarea sa într-un fişier.
Informaţiile sunt de tip text, adică o mulţime de caractere, structurate în linii.
Principalele funcţiuni ale unui editor de texte sunt:
vizualizarea unei părţi a textului;
deplasarea şi poziţionarea în fişier (se indică poziţia curentă);
modificarea textului prin inserare, modificare, ştergere;
regăsirea şirurilor de caractere particulare.
Editorul poate fi utilizat atât pentru tastarea textului sursă al unui
program cât şi pentru introducerea datelor necesare programului.
Vom evidenţia două dintre cele mai importante tipuri de editoare:
a) editor sintactic, adaptat prelucrării programelor sursă, care verifică
sintaxa programelor pe măsura tastării acestora, permiţând de
asemenea gestionarea automată a structurilor sintactice proprii
limbajului de programare utilizat;
b) procesor de texte, destinat tratării textelor. Acest tip de editor oferă
funcţionalităţi mult mai pronunţate pentru manipularea caracterelor:
utilizarea literelor accentuate, fonturi diferite (adică diferite seturi de
caractere), alinierea textului, inserare de desene etc., mai general se
zice că aceste editoare oferă facilităţi de punere în pagină pentru
scriere de scrisori, articole, cărţi etc.
Compilatorul
Un compilator este un program sistem care traduce un program sursă
scris într-un limbaj de programare de nivel înalt în program obiect.
Activitatea compilatorului se divide în două mari componente:
a) faza de analiză, care cuprinde următoarele etape:
analiza lexicală;
analiza sintactică;
analiza semantică.
b) faza de sinteză, care cuprinde următoarele etape:
generarea codului intermediar;
optimizarea codului;
generarea codului obiect.
Activitatea compilatorului este prezentată schematic astfel:
99
program
sursă
analiza semantică
generarea codului
intermediar
optimizarea
codului
generarea codului
obiect
Compilator
program obiect
Analiza lexicală
Analiza lexicală este prima fază a compilării. Rolul său major constă în
citirea secvenţei de caractere care constituie programul sursă şi producerea
unor secvenţe de elemente sintactice ale limbajului.
Identificatorii, de exemplu numele de variabile, sau de proceduri ca şi
atributele lor sunt stocate într-o tabelă de simboluri, în timp ce informaţiile
inutile pentru compilator (comentariile) sunt eliminate.
100
Analiza sintactică
Analizorul sintactic primeşte o listă de elemente sintactice (cuvinte
rezervate, identificatori, operatori aritmetici, semne de punctuaţie etc.)
elaborată de către analizorul lexical, verifică corectitudinea ei în raport cu
sintaxa limbajului şi generează arborele sintactic al programului.
Sunt posibile două abordări pentru generarea arborelui sintactic:
ascendentă: se analizează elementele componentr ale frazei de tratat
şi se caută regulile care permit ascensiunea spre rădăcină;
descendentă: se porneşte de la rădăcină şi se aplică regulile care
permit construirea frazei dorite.
Analiza semantică
Analiza semantică vizează sensul şi semnificaţia frazelor limbajului, utilizând
arborele sintactic pentru a identifica operatorii şi operanzii instrucţiunilor.
Sarcina principală a unui analizor semantic este verificarea concordanţei
tipurilor, ceea ce revine la a verifica dacă fiecare operator acţionează asupra
operanzilor care sunt autorizaţi prin limbaj. Pentru efectuarea acestor verificări,
analizorul semantic utilizează informaţiile care sunt stocate în tabela de simboluri.
Optimizarea codului
Optimizarea codului constă în ameliorarea codului pentru a-l face mai
rapid de executat şi mai puţin „încurcat” în memorie, şi vizează în special
eliminarea redondanţelor şi evaluarea expresiilor care utilizează constante.
Optimizarea conduce la o creştere substanţială a timpului de compilare,
deci este de preferat evitarea acestei faze în timpul elaborării programelor.
Optimizarea codului joacă un rol determinant pentru sistemele de calcul
care utilizează un procesor RISC, datorită complexităţii compilatoarelor
pentru astfel de maşini, care utilizează un număr mare de registre în vederea
reducerii numărului de accese la memoria centrală.
101
Generarea codului obiect
Generarea codului obiect este fază finală a compilării, care generează
codul obiect relocabil, adică relativ la originea 0. Fiecare instrucţiune a
codului intermediar este tradusă într-o secvenţă de instrucţiuni în cod obiect.
Generarea codului obiect atribuie poziţii în memorie pentru datele şi
instrucţiunile programului.
Tabela de simboluri
În timpul compilării este necesară descrierea identificatorilor şi a
caracteristicilor acestora. Tabela de simboluri permite gruparea acestor
informaţii care sunt puse la dispoziţia diferitelor faze ale compilatorului.
În tabelă se găsesc numele variabilelor, constantelor şi procedurilor.
Fiecărei intrări din tabelă i se asociază o înregistrare care conţine numele
obiectului considerat şi caracteristicile proprii (tip, adresă numerică, numărul
şi tipul parametrilor etc.). Accesul la această tabelă trebuie să fie rapid,
deoarece toate fazele compilării pot utiliza tabela de simboluri.
Tratarea erorilor
În activitatea practică de programare s-a constatat că este dificilă scrierea
programelor fără erori şi din această cauză, un bun compilator trebuie să
facă posibilă detectarea şi corectarea acestor erori.
La sfârşitul compilării se întocmeşte un raport al erorilor depistate şi se
încearcă specificarea cauzei care a generat eroarea precum şi poziţia sa în
cadrul textului sursă.
Un program scris într-un limbaj de pogramare evoluat poate conţine erori
de natură diferită:
a) erori lexicale: erori de ortografiere a identificatorilor sau cuvintelor
rezervate, caractere ilegale etc.
b) erori sintactice: constituie majoritatea erorilor de programare şi se
referă la: expresii aritmetice sau logice incorecte, erori de structurare
a blocurilor, lipsa separatorilor etc.
c) erori semantice: identificatori nedeclaraţi, incompatibilitate între
operatori şi operanzi etc.
d) erori logice: erori aritmetice de tipul împărţirii cu zero, rădăcină
pătrată dintr-un număr negativ, depăşirea limitelor unui tablou, ciclu
infinit, adresare incorectă etc.
Erorile din primele trei categorii sunt detectate de compilator în timpul
analizei cu acelaşi nume (analiza lexicală, sintactică, semantică), şi sunt
relativ uşor de corectat deoarece compilatorul indică prezenţa lor.
102
Erorile logice sunt vizibile doar la execuţie şi au ca efect fie efectuarea
unor calcule eronate, fie oprirea execuţiei programului. Acestea sunt erorile
cele mai dificil de detectat şi corectat, şi la fiecare tentativă de corectare
trebuie reluat ciclul compilare - execuţie - testare.
Editorul de legături
Un editor de legături linkage editor este un produs software ce permite
combinarea mai multor programe obiect, obţinându-se un singur modul obiect.
Figura următoare prezintă un exemplu de editare de legături pentru un
program care conţine două subprograme traduse şi stocate în fişiere separate,
şi care face de asemenea apel la două module de bibliotecă care sunt traduse
în prealabil şi conservate în cod obiect.
editare de legături
program
complet
executabil
103
Dezvoltarea unor programe complexe se realizează prin descompunerea
acestora în module care se traduc independent, deci un program poate fi
constituit din mai multe fişiere (sau subprograme), unul dintre fişiere
conţinând în mod obligatoriu programul principal.
Toate aceste fişiere sunt traduse separat, ele pot utiliza subprograme care
se găsesc în alte fişiere, ceea ce dă naştere la referinţe exterioare.
Există două tipuri de referinţe exterioare:
a) posibilitatea ca un modul să apeleze alt modul sau subprogram de
bibliotecă;
b) posibilitatea ca un modul să fie referit de un alt modul;
Referinţele exterioare unui modul ridică probleme deosebite pentru
programul traducător care nu poate satisface referinţele exterioare ci doar
întocmeşte o listă a acestora pe care o transmite editorului de legături.
Editorul de legături preia modulele independente, le grupează şi satisface
referinţele exterioare pentru a forma un program complet, care este executabil.
Programul încărcător
Programul obiect care rezultă în urma editării de legături, trebuie să fie
încărcat în memoria calculatorului pentru a putea fi executat. Programul
încărcător loader, care este de obicei cuplat cu editorul de legături
realizează încărcarea programului obiect la adresa sa de încărcare.
Există două tipuri de programe încărcătoare:
a) încărcător absolut, specific vechilor sisteme de calcul care permite
încărcarea programului (unic în memorie) la o adresă fixată în avans,
ca şi toate adresele din cadrul programului.
b) încărcător relocabil, specific noilor tipuri de sisteme
multiprogramate, care utilizează pentru încărcare în memorie
tehnica relocării. O modalitate de realizare a relocării este aceea a
utilizării indicatorului de relocare de către programul traducător în
câmpul de adresă al instrucţiunii. Relocarea se mai poate realiza prin
intermediul unui registru de bază, astfel:
se traduce programul în raport cu adresa 0 şi se realizează
editarea de legături;
se alege un registru de bază printre cele disponibile;
se depune în registrul de bază adresa de bază (adresa absolută a
programului);
se încarcă programul în memorie, pornind de la adresa de bază, fără
modificarea adreselor programului. În timpul execuţiei, la fiecare
referire a unei adrese, sistemul de calcul efectuează operaţiile:
104
adresa efectivă = adresa de bază + adresa referită.
6 STRUCTURI DE DATE
Numere
Memorie în virgulă
mobilă
Nivel maşină
Cuvinte
Numere întregi
Octeţi
Registre
Biţi
105
Structurile de date sunt construite pornind de la datele elementare
realizate la nivel maşină. Utilizatorul poate să lucreze şi cu informaţii mai
complexe , deci la un nivel superior de abstractizare, fără să ţină seama de
detaliile implementării fizice a acestor structuri care sunt „ascunse” de
limbajul de programare şi software-ul asociat (traducător, interpretor, etc.).
Utilizatorul poate defini structuri de date şi mai complexe (arbori, tabele,
liste, etc.) utilizând datele structurate la nivelul limbajului de programare.
Pentru a introduce o nouă structură abstractă se procedează astfel :
- se defineşte structura informaţiei;
- se definesc operaţiile aplicabile acelei structuri;
- se lucrează cu această informaţie structurată la acest nivel de
abstractizare, fără a se ţine seamă de detaliile de implementare;
Există un mare număr de structuri de date. Vom prezenta câteva
exemple dintre structurile cele mai utilizate: vectori, tablouri, liste, arbori,
cozi, stive şi tabele.
Vectori
Vectorii vectors sunt structuri foarte utile, folosite de majoritatea
limbajelor de programare (procesoarele vectoriale suportă vectorii la nivel
hardware). Un vector este o mulţime finită şi ordonată de elemente, toate de
acelaşi tip. El este definit prin numărul de elemente, ca şi prin tipul şi
mărimea lor, stabilindu-se o corespondenţă imediată între structura abstractă
şi organizarea în memorie. Figura următoare prezintă schematizat structura
unui vector:
1 2 3 4 5 6 7 n-1 n
Tablouri
Un tablou array este o colecţie multidimensională de obiecte de
acelaşi tip. Un tablou cu o singură dimensiune este un vector. Fiecare
element al tabloului este reperat printr-un set de indici subscripts. Accesul
la informaţia conţinută într-un tablou este deci aleator. Realizarea unui
tablou multidimensional utilizează vectori, iar specificarea dimensiunilor
necesită o declaraţie în cadrul programului.
Liste
Listele lists sunt structuri suple capabile să conţină un număr
nedeterminat de obiecte. Dacă fiecare obiect este accesibil prin cel precedent
106
datorită unui pointer, atunci avem de a face cu o listă legată sau înlănţuită
linked list. Un astfel de exemplu este prezentat în figura următoare:
Pointer către
elementul următor
Arbori
Arborele este o structură constituită din noduri legate prin arce. Fiecare
nod conţine un obiect al colecţiei. Arborele este o structură ierarhică. În vârf
există un nod numit rădăcină, de la care pornesc ramurile, către nodurile
nivelului inferior. Nodurile terminale se numesc frunze.
Arborele binar este un caz particular în care fiecare nod posedă cel mult
două ramuri către nodurile nivelului inferior.
Implementarea în memorie a unui arbore se poate realiza cu ajutorul
pointerilor. Fiecărui nod îi corespunde un ansamblu de cuvinte de memorie
care conţin datele şi pointerii reprezentând ramurile care pleacă din nod.
Cozi
O coadă este un fir de aşteptare (FIFO = First In First Out). Inserările se
realizează la o extremitate iar extragerile se fac la celălalt capăt. Realizarea
este posibilă cu ajutorul unui vector şi a doi pointeri.
Pentru a evita deplasarea cozii în memorie, se poate defini o zonă de
memorie circulară, adică prima adresă să urmeze după ultima adresă. Un
pointer pointează asupra ultimului element din coadă, unde se adaugă datele,
iar al doilea pointer indică primul element, unde se extrag datele.
Stive
O sivă LIFO = Last In First Out este o structură liniară particulară, în
care datele sunt adăugate sau extrase la o extremitate predeterminată.
Stiva este una dintre structurile cele mai importante şi mai utilizate (de
exemplu: recursivitate, întreruperi multinivel, maşină pe 0 adrese etc.).
107
Implementarea în memorie a unei stive se poate face cu ajutorul unui
vector şi a unui pointer care indică vârful stivei, unde datele sunt depuse sau
de unde sunt extrase.
Tabele
În capitolul precedent am descris tabelele utilizate de asamblor şi
compilator pentru păstrarea simbolurilor şi valorilor corespunzătoare.
Se poate defini o tabelă ca o structură în general neordonată de date de
acelaşi tip, unde fiecare dată are asociată o informaţie unică numită cheie şi
care serveşte la identificarea elementului tabelei. De exemplu, dacă vom
considera o agendă telefonică, cheia este numele abonatului iar informaţiile
asociate pot fi adresa şi numărul de telefon.
Căutarea unui element în tabelă se realizează prin specificarea cheii.
Deşi au fost elaborate mai multe metode de căutare în tabele, nu există o
tehnică universală şi optimală, alegerea depinzând de tipul şi talia tabelei,
precum şi de specificul utilizării sale.
Vom prezenta trei algoritmi de căutare în tabele utilizaţi frecvent în
programare: căutarea liniară, căutarea binară şi adresajul dispersat.
Căutarea liniară
Tabelele de simboluri, construite în timpul primei treceri ale unui
asamblor şi în timpul fazelor de analiză lexicală şi sintactică ale unui
compilator, asociază numele simbolic al unei variabile sau al unui
identificator oarecare utilizat drept cheie a tabelei un anumit număr de
atribute, ca de exemplu: tip, adresă, protecţie, etc. Atunci când traducătorul
întâlneşte un simbol, el trebuie să verifice dacă există deja în tabelă, altfel
trebuie să stabilească o nouă intrare în tabelă.
Deoarece nici simbolurile şi nici ordinea de prezentare nu sunt
cunoscute în prealabil, traducătorul introduce datele în tabelă, pe măsură ce
întâlneşte noi simboluri în programul sursă, deci tabela este nesortată.
Pentru a găsi un element în tabelă se poate utiliza metoda de căutare
liniară. Este cea mai simplă metodă, dar şi cea mai puţin performantă. Ea
constă în a parcurge tabela începând cu primul element şi comparând fiecare
nume cu cheia de căutare. Cu o tabelă de n elemente, timpul mediu de
căutare este proporţional cu n / 2.
Dezavantajul unei astfel de metode este deci numărul mare de
comparaţii. Avantajele se referă la uşurinţa de realizare, aplicarea ei pentru
tabele nesortate (sortarea unei tabele ia mult timp) şi faptul că pot fi
efectuate căutări în timpul încărcării tabelei.
108
Căutarea binară
Printre tehnicile rapide, dar care impun existenţa unei tabele ordonate,
se poate cita căutarea binară sau dihotomică binary search.
Ideea constă în a considera cheile ca fiind uniform distribuite şi deci de a
începe căutarea prin compararea cheii date cu cea plasată în mijlocul tabelei.
Această comparare permite eliminarea dintr-o dată a unei jumătăţi a tabelei. Se
poate continua în acelaşi mod aplicând metoda pentru elementele rămase
ş.a.m.d. Metoda converge rapid şi durata căutării este proporţională cu log2(n).
Figura următoare prezintă comparativ cele două căutări şi se observă că
metoda de căutare liniară necesită 13 comparări în timp ce metoda
comparării binare necesită doar 4 comparări ale cheii (caută: mmmmm).
Căutare liniară Căutare binară
Tabela nesortată Tabela sortată
1 ccccc aaaaaa
2 ggggg bbbbb
3 zzzzz ccccc
4 sssss ddddd
5 eeeee eeeee
6 hhhhh fffff
7 kkkkk ggggg
8 lllll hhhhh
9 qqqqq iiiii
10 aaaaa jjjjj 1
11 ddddd kkkkk
12 fffff lllll 3
13 wwwww mmmmm 4
14 mmmmm nnnnn
ooooo ooooo 2
ttttt ppppp
bbbbb qqqqq
109
rrrrr rrrrr
uuuuu sssss
Avantajul acestei tehnici provine din numărul redus de comparaţii
necesare pentru a găsi obiectul dorit. Pentru o tabelă cu 1000 de date,
căutarea binară va putea găsi orice cheie din 10 comparări, în timp ce
căutarea liniară ar necesita în medie 500 de comparări.
Adresaj dispersat
O soluţie ideală ar fi ca să existe un mecanism de căutare rapidă care să
nu impună ca tabela să fie ordonată. Memoriile asociative realizează o
căutare paralelă pe toate cheile, dar o memorie asociativă de mare capacitate
este costisitoare. Pentru simularea comportamentului unei memorii
asociative (acces aleator) se poate utiliza metoda de adresaj dispersat
(hashing, hash code).
Această tehnică foarte utilizată constă în evidenţierea unei funcţii de
hashcode, care se aplică cheii şi furnizează o adresă sau un indice în tabela
asociată. Funcţia de hashcode este importantă, ea trebuie să furnizeze adrese
destul de uniform distribuite în intervalul de adrese disponibile.
Dacă aplicarea funcţiei de hashcode asupra a două nume de simboluri
alese drept cheie dă acelaşi rezultat, adică cele două obiecte ar trebui să fie
plasate la aceeaşi adresă, spunem că s-a realizat o coliziune. O bună funcţie
de hashcode trebuie să genereze un număr minim de coliziuni.
Este foarte clar că spaţiul de adrese din cadrul tabelei trebuie să fie
suficient pentru a conţine toate obiectele.
Pentru rezolvarea coliziunilor se pot utiliza mai multe strategii:
- liste înlănţuite pentru adresarea obiectelor implicate, fiecare listă să
înceapă la adresa comună;
- repetarea calculului de adresă cu o a doua funcţie de hashcode;
- plasarea obiectului care găseşte locul ocupat la adresa următoare
sau la prima adresă disponibilă (presupune o tabelă generos
dimensionată, şi în plus o căutare liniară).
Metoda adresajului dispersat permite stabilirea unei relaţii funcţionale
cheie-adresă, de aceea căutarea în tabele se limitează la o singură comparare
(exceptând coliziunile) după calculul adresei cu ajutorul funcţiei de
hashcode.
110
Structurile de date prezentate sunt adaptate organizării memoriei
centrale, adresabile prin cuvinte sau octeţi.
Fişierele sunt o structură adaptată memoriilor auxiliare (unităţi de bandă
şi discuri magnetice).
Un fişier este o colecţie de date reprezentând o entitate pentru utilizator.
În mediul informatic, datele unui fişier sunt înregistrate astfel încât să fie
facilitată citirea şi prelucrarea acestora cu calculatorul. În acest context, un
fişier este deci o colecţie de date, rezultate, un text, un program sursă, un
program binar executabil etc. Un fişier este conceput ca o colecţie de
înregistrări. Prezentarea detaliată a conceptului de fişier va fi realizată în
capitolul următor.
O bază de date este un ansamblu structurat de date. Conţinutul unei
baze de date este cunoscut sub numele de bancă de date.
O bază de date permite regruparea şi centralizarea informaţiilor
necesare diverselor aplicaţii în vederea unei mai bune repartizări.
Din punct de vedere logic, o bază de date (BD) data base este
constituită din mulţimea informaţiilor relative la un subiect dat. Această
mulţime trebuie să respecte următoarele criterii:
- exhaustiviate : informaţii complete despre un subiect dat;
- neredondanţă : unicitatea informaţiilor în baza de date;
- structură : asigură o bună gestionare a bazei de date.
Din punct de vedere fizic, o bază de date este o virtualizare a noţiunii de
fişier. În general, bazele de date sunt stocate pe discuri magnetice şi gestiunea
lor se efectuează direct asupra discurilor. O bază de date este implementată cu
fişiere dar acest aspect nu este transparent pentru utilizatori. Stocajul fizic al
unei baze de date constă într-o mulţime de înregistrări fizice organizate cu
ajutorul listelor, pointerilor şi diverselor metode de indexare.
Operaţiile care se pot efectua asupra unei baze de date sunt :
- interogare sau consultare;
- actualizare;
- inserare;
- suprimare.
Pentru efectuarea acestor operaţii sunt necesare programe adecvate,
reunite sub denumirea de Sistem de gestiune de baze de date (SGBD)
DBMS : DataBase Management System.
Un aspect important al bazelor de date actuale este independenţa datelor
faţă de aplicaţii, ceea ce constituie principalul obiectiv al bazelor de date. În
vederea asigurării unei accesibilităţi sporite a informaţiilor se realizează o
separare între problemele de stocaj şi întreţinere, pe de o parte, şi
111
problemele de prelucrare ale utilizatorilor, pe de altă parte, realizându-se
astfel o independenţă între date şi metodele de acces.
Pentru simplificarea problemelor de acces s-au elaboart mai multe
modele logice de baze de date: modelul ierarhic, modelul reţea, modelul
relaţional şi modelul pe obiecte.
Modelul ierarhic constă în organizarea datelor de manieră
arborescentă, ceea ce constituie o structură simplă care este o ierarhie în care
fiecare element nu are decât un superior, fără a exista conexiuni între
ramurile de pe acelaşi nivel.
Modelul reţea este o extensie a modelului precedent deoarece permite
stabilirea conexiunilor între elemente diferite. În acest mod se poate realiza
un mare număr de interogări posibile, dar acestea trebuiesc prevăzute la
construirea bazei de date. În această clasă de SGBD, modelul CODASYL
este unul din cele mai răspândite.
Modelul relaţional (de exemplu: SGBD Ingres, SQL/DS, Oracle,
Informix, Access etc.) permite eliminarea constrângerii de cunoaştere în
avans a interogărilor care se vor efectua, permiţând stabilirea conexiunilor în
momentul execuţiei.
Datele sunt stocate sub formă de relaţii în tabele, iar accesul la
informaţii se efectuează prin aplicarea celor trei operaţii de bază: selecţia,
proiecţia, compunerea.
Selecţia constă în extragerea dintr-o relaţie a acelor elemente care
satisfac o condiţie.
Proiecţia permite izolarea unui număr de coloane dorite.
Compunerea produce noi tabele pornind de la tabele existente.
Bazele de date permit definirea unei structuri logice deasupra structurii
fizice (cea de fişiere pe disc) care nu este adaptată manipulării datelor.
Interfaţa dintre o aplicaţie şi o bază de date este efectuată cu ajutorul
limbajelor specifice, dintre care cel mai cunoscut este SQL. Limbajul SQL
Structured Query Language este un limbaj standard de definire şi
manipulare a datelor din bazele de date relaţionale.
Modelul pe obiecte este un sistem de baze de date orientate obiect
OODB-Object Oriented DataBases. Principiul acestui nou model este
relativ simplu, el constă în a utiliza aceleaşi structuri de date în aplicaţie şi în
baza de date, realizând astfel o corespondenţă directă între aplicaţie şi baza
de date.
Aceste structuri de date sunt clase de obiecte şi baza de date este o bază
de obiecte. Obiectele bazei de date sunt obiecte persistente şi care
beneficiază de polimorfism şi moştenire ceea ce garantează o bună
flexibilitate.
112
Conceptul de obiect a dat naştere unei noi tehnologii care se aplică în
numeroase domenii, de exemplu: limbajele de programare, sistemele de
operare şi bazele de date.
7 SISTEME DE OPERARE
113
deosebită a sistemului de operare, în lumea informaticii se spune că „un
elefant este un şoricel împreună cu sistemul său de operare”.
114
acest sens cu un nou modul, planificatorul scheduler, care
asigură planificarea lucrului.
d) Multiprogramarea. Un sistem de calcul este multiprogramat dacă
mai multe programe sunt încărcate în memorie în scopul partajării
CPU-ului, asigurându-se exploatarea mai eficientă a sistemului de
calcul prin eliminarea perioadei de aşteptare a unităţilor de prelucrare
în timpul operaţiilor de intrare/ieşire. Sistemul de operare va conţine
un nou modul, alocatorul, care asigură gestiunea CPU ţinând cont de
sistemul de priorităţi gestionat de către planificator, dar poate decide
de asemenea întreruperea unei execuţii prelungite fără să aştepte o
operaţie de intrare-ieşire în vederea unei partajări echitabile a CPU-
ului. Multiprogramarea ridică o serie de probleme:
partajarea unităţii de prelucrare între programe şi salvarea
contextului (starea de execuţie) pentru fiecare program;
gestiunea memoriei centrale încât să permită încărcarea unui
număr ridicat de programe într-un spaţiu limitat;
gestiunea intrărilor/ieşirilor pentru diversele programe, asigurând
transferul de date între memorie şi unităţile periferice şi împiedicând
sistemul să „amestece” informaţiile specifice programelor;
protejarea programelor şi a datelor stocate în memoria centrală
şi pe disc, eventualele erori putând avea consecinţe grave
asupra derulării operaţiilor;
e) Sistemele în timp partajat time-sharing, numite de asemenea
multiacces sau multiutilizator, sunt o variantă a sistemelor
multiprogramate în care timpul CPU este distribuit în mici tranşe egale
unui mare număr de utilizatori interactivi, conectaţi la sistem. Sistemele
actuale combină prelucrările batch şi time-sharing. Într-un sistem în timp
partajat, orice job lansat de la un terminal poate fi direct controlat de
către utilizator, care are posibilitatea, de exemplu, să decidă corectarea
erorilor, recompilarea şi relansarea în execuţie. Acest mod de exploatare
este adaptat în special fazei de punere la punct a unui program, în timp ce
modul batch este utilizat în general pentru aplicaţii care vizează activităţi
de producţie şi pentru alte sarcini interactive.
Caracteristicile sistemelor de operare pentru sistemele
multiprogramate vizează următoarele aspecte:
a) Exploatarea resurselor este o sarcină fundamentală care asigură:
paralelismul între diverse activităţi în vederea creşterii
performanţelor sistemului de calcul. Noţiunea de procese
paralele şi concurente facilitează înţelegerea funcţionării unui
sistem de calcul multiprogramat;
115
partajarea resurselor şi a informaţiilor este asigurată prin
gestiunea diferitelor unităţi funcţionale ale sistemului (CPU,
memorie centrală şi auxiliară, dispozitive de intrare/ieşire),
permiţând acccesul simultan la datele comune (baze de date,
fişiere etc.) şi la anumite programe (utilitare, biblioteci etc.);
interdependenţa între funcţiunile sistemului de operare şi
alte funcţiuni, deoarece nu există o distincţie netă între ele, de
exemplu, compilatorul şi editorul de texte sunt considerate
programe utilitare, iar în sistemul Unix, modulul de gestiune a
fişierelor este tratat ca o aplicaţie oarecare;
nedeterminismul operaţiilor care vizează caracteristica de
comportament a sistemelor de operare. Dacă la nivelul unei aplicaţii,
execuţii repetate cu aceleaşi date produc aceleaşi rezultate, sistemul
de operare trebuie să reacţioneze la situaţii nereproductibile, la
evenimente aleatoare, ca de exemplu, întreruperi generate de
dispozitive de intrare/ieşire, transferuri de date repetate ca urmare a
erorilor detectate în urma verificărilor de paritate etc.
b) Virtualizarea sistemului prezintă utilizatorului, prin intermediul
limbajului de comandă, o maşină virtuală mai uşor de programat
decât cea reală. Limbajul de comandă furnizează modalitatea de a
comunica sistemului, prin formularea de cereri, toate informaţiile
necesare diferitelor etape de lucru. Deşi există o oarecare asemănare
între limbajele de comandă şi cele de programare în sensul
formulării unor fraze care specifică într-un mod neambiguu acţiuni
de executat, totuşi, instrucţiunile unui limbaj evoluat de programare
sunt în mod normal executate de către CPU după ce au fost traduse
de către compilator, în timp ce comenzile unui limbaj de comandă
sunt interpretate de către sistemul de operare. Maşina virtuală
„ascunde” utilizatorului toate detaliile privind, de exemplu, o
operaţie de intrare/ieşire sau o manipulare de fişiere;
c) Dispozitivele esenţiale pentru sisteme multiprogramate, ca de
exemplu, canale de intrare/ieşire, sistemul de întreruperi, memoriile
auxiliare şi terminalele interactive, la care se adaugă alte dispozitive
pentru protecţia programelor şi a datelor, pentru relocarea dinamică
a programelor sau pentru gestiunea memoriei virtuale stau la baza
oricărui sistem de operare modern;
d) Maşină cu două stări:
starea supervizor, rezervată sistemului de operare;
starea utilizator, în care intră programele de aplicaţie.
116
Această concepţie permite dotarea sistemului cu un set instrucţiuni
de bază, executabile în cele două stări, şi câteva instrucţiuni
suplimentare, instrucţiuni privilegiate, executabile numai în mod
supervizor. Starea sistemului este specificată prin poziţionarea unui
indicator accesibil pentru modificare doar sistemului de operare (de
exemplu, un bit al registrului de stare). În anumite situaţii,
indicatorul de stare trece automat în starea supervizor, de exemplu
în cazul unei întreruperi sau în caz de eroare, sau în general, ca
urmare a unui eveniment care necesită intervenţia sistemului.
Interfaţa între cele două stări este asigurată prin existenţa unei
instrucţiuni neprivilegiate, numită cerere a supervizorului.
e) Program, procesor, proces. Un program este o secvenţă statică de
instrucţiuni. Un procesor execută instrucţiunile unui program. Un proces
este o acţiune, o secvenţă de operaţii care se derulează pentru realizarea
unei sarcini determinate, pe scurt, este un program în execuţie.
117
....
gestiunea memoriei centrale
hardware
Nucleul sistemului de operare
Funcţiunile principale ale nucleului kernel sunt următoarele:
a) alocarea CPU;
b) gestiunea întreruperilor;
c) gestiunea proceselor.
Nucleul este singura componentă a SO în întregime rezidentă în memoria
centrală. Funcţiunile sale implică intervenţii frecvente şi rapide. De aceea, şi
datorită ocupării permanente a unei părţi din memorie, codificarea nucleului
trebuie realizată cu mare atenţie şi optimizată.
Este într-adevăr nivelul cel mai solicitat al sistemului, codificat adesea în
limbaj de asamblare, restul sistemului fiind codificat în limbaj de
programare evoluat orientat sistem (C, Pascal concurent, Modula-2).
Alocare CPU
Alocatorul (dispecerul) este responsabil cu repartizarea timpului
disponibil unităţii de prelucrare (sau unităţilor de prelucrare în cazul
arhitecturilor multiprocesor) între diferite procese.
Sarcina sa implică gestiunea unui fir de aşteptare, unde procesele care
sunt gata să utilizeze CPU sunt clasate în ordinea priorităţii. Prioritatea
este atribuită de planificator în funcţie de urgenţa prelucrării şi resursele
solicitate şi este modificată dinamic pe baza timpului de aşteptare între două
execuţii parţiale. Dispecerul alocă CPU procesului care se găseşte în capul
cozii în momentul în care CPU devine disponibil.
Dispecerul trebuie de asemenea să salveze starea (contextul) procesului a
cărui execuţie s-a întrerupt şi trebuie să furnizeze CPU-ului elementele de
context (echipament) ale procesului desemnat ca succesor.
Pentru salvarea informaţiilor privind starea proceselor, se asociază
fiecărui proces o zonă de memorie conţinând toate informaţiile esenţiale ca:
identificator, paritate, context, statut (de exemplu activ, dacă este stăpân al
CPU; gata de execuţie, dacă este încărcat în memorie şi dispune de toate
resursele, fără CPU; în aşteptare, dacă este pe disc în aşteptarea posesiei
118
perifericelor şi spaţiului de memorie necesare; suspendat, dacă execuţia sa a
fost întreruptă; terminat, dacă procesul şi-a realizat sarcinile şi execuţia sa a
luat sfârşit), necesităţile în resurse etc.
Acest bloc de informaţii se numeşte vector de stare, sau descriptor, sau
imaginea procesului. Aceşti descriptori sunt regrupaţi într-o structură de
date şi pot fi accesaţi printr-un pointer pornind de la o tabelă centrală.
Această structură este accesibilă programelor nucleului.
Dispecerul este solicitat în toate cazurile în care trebuie schimbat
procesul stăpân al CPU. De exemplu când procesul executant declanşează o
operaţie de intrare/ieşire, sau când o întrerupere de ceas semnalează că
tranşa de timp alocată este epuizată şi trebuie suspendată execuţia, atunci
trebuie atribuit CPU unui alt proces.
Dispecerul va fi de asemenea activ când o întrerupere externă modifică
starea procesului stăpân al CPU, sau îl face pe moment inoperant (de
exemplu tratarea unei erori).
Gestiunea proceselor
Un proces (task) este un calcul care poate fi executat concurent sau în
paralel cu alte calcule. El este o abstractizare a procesorului, fiind considerat
ca un program în execuţie.
Existenţa unui proces este condiţionată de existenţa a trei factori:
a) o procedură (un set de instrucţiuni) care trebuie executată;
b) un procesor care să poată executa aceste instrucţiuni;
c) un mediu (memorie, periferice) asupra căruia să acţioneze
procesorul conform celor precizate în procedură.
119
întâi se execută complet S1 şi apoi S2, sau se execută complet S2 şi apoi S1,
sau execuţia uneia începe înaintea terminării execuţiei celeilalte.
S1 S2 S1 S1
S3 S2 S3
S4 S4 S2
S5 S6
S7 S3
Grafuri de precedenţă Graf de neprecedenţă
Condiţii de paralelism
Notăm R (Si) a1, a2, ..., am mulţimea tuturor variabilelor referite în
instrucţiunea Si fără a fi modificate;
Notăm W (Si) b1, b2, ..., bn mulţimea tuturor variabilelor referite şi
modificate în instrucţiunea Si;
120
În cazul grafurilor de precedenţă prezentate anterior, R (S1) ; R
(S2) ; W (S1) a; W (S2) b, deci concurenţa este posibilă, dar S2
şi S3 nu pot fi executate concurent deoarece W(S2) W(S3) a .
Mecanismul PARBEGIN-PAREND
O astfel de construcţie are forma: S0; PARBEGIN S1 S2...Sn
PAREND; Sn+1; şi corespunde grafului de precedenţă următor:
121
S0
S1 S2 ... Sn
Sn+1
Deci instrucţiunile S1, S2, ..., Sn sunt lansate în execuţie simultan şi sunt
executate concurent. Prezentăm descrierea grafurilor de precedenţă din
figura anterioară cu PARBEGIN-PAREND.
S1:
PARBEGIN
begin
PARBEGIN S2;
read (a); S4;
read (b); PARBEGIN
PAREND S5;
c := a+ b; S6;
write (c); PAREND
end;
S3;
PAREND
S7;
Prezentăm în continuare un exemplu de copiere a unui fişier F într-un
fişier G, situat pe un suport diferit, folosind instrucţiuni concurente:
Type articol record . . . end;
Var F, G: file of articol;
w, r: articol;
begin
reset (F);
rewrite (G);
read (F, r);
while not eof (F) do begin
w:r;
PARBEGIN
read (F, r); | write (G, w);
PAREND;
end;
122
write (G,r);
close (F);
close (G);
end.
Conceptul de semafor
Un semafor s este o pereche (v (s), c (s)), unde v (s) este valoarea
semaforului (valoarea iniţială v0 (s)), iar c (s) o coadă de aşteptare care
conţine pointeri la procesele care aşteaptă la semaforul s. Pentru gestiunea
semafoarelor se definesc două operaţii primitive: WAIT şi SIGNAL.
1 b*b 1 PARBEGIN
2 4*a r1 : - b
3 (4 * a) * c r2 : b * b
4 (b * b) - (4 * a * c) r3 : 4 * a
123
5 sqrt (b * b - 4 * a * c) r4 : 2 * a
6 -b PAREND
7 (- b) + sqrt (b * b - 4 * a * c) 2 r5 : r3 * c;
8 2*a 3 r5 : r2 - r5;
9 (- b) + sqrt (b*b - 4*a*c)/ (2*a) 4 r5 : sqrt (r5);
5 r5 : r1 + r5
6 x : r5 / r4;
Secţiune critică, resursă critică, excludere mutuală
Problema secţiunii critice constă în aceea că două sau mai multe procese
concurente încearcă să modifice o aceeaşi variabilă, de un număr neprecizat
de ori:
PARBEGIN
P1: . . . v : v + 1; . . .
P2: . . . v : v + 1; . . .
PAREND
var s:semafor;
v0 (s):1;
PARBEGIN
P1: repeat
WAIT (s);
secţiune critică;
SIGNAL (s);
rest program1
until false
P2: repeat
WAIT (s);
secţiune critică;
SIGNAL (s);
rest program2
until false
124
PAREND
Sincronizarea proceselor
Operaţia de sincronizare a două procese se enunţă astfel: Procesul P1 nu poate
trece de un anumit punct A decât după ce procesul P2 ajunge într-un punct B.
Utilizând semafoarele, procesul P1 va aştepta în punctul A, prin operaţia WAIT (s),
până când procesul P2 va efectua în punctul B operaţia SIGNAL (s).
var s:semafor;
v0 (s) : 0;
PARBEGIN
P1: repeat . . . A: WAIT (s); . . . until false;
P2: repeat . . . B: SIGNAL (s) . . . until false;
PAREND
125
WAIT (exclus);
extrage articol din buffer;
SIGNAL (exclus);
SIGNAL (gol);
consumă articol;
until false
PAREND
Problema impasului
Problema impasului se manifestă în următoarea situaţie când ambele
procese sunt blocate.
var x,y: semafor;
v0 (x) : 1;
v0 (y) : 1;
PARBEGIN
A: . . . WAIT (x); . . . WAIT (y);
B: . . . WAIT (y); . . . WAIT (x);
PAREND
Impasul este o stare foarte gravă care poate duce la blocarea sistemului
de operare sau la distrugerea unor procese.
126
crearea unui punct de reluare, care este o fotografie a
memoriei pentru procesul „victimă“ şi pentru procesele cu
care colaborează;
b) Detectarea unui impas dacă sistemul posedă un mecanism de
prevenire a impasului (de exemplu, detectarea ciclurilor în graful de
alocare a resurselor);
c) Prevenirea impasului se face prin urnmătoarele metode:
Metoda 1: „totul sau nimic”. Procesul cere resurse în momentul
încărcării, iar SO întocmeşte graful alocării resurselor;
Metoda a 2-a: cererea de resurse într-o anumită ordine, prin
numerotarea resurselor;
Metoda a 3-a: alocare şi suspendare controlată.
Gestiunea întreruperilor
Întreruperile sunt constituite dintr-un ansamblu de rutine, fiecare dintre
ele fiind activată la apariţia unui semnal fizic de întrerupere.
Sarcina modulului de gestiune a întreruperilor este determinarea sursei
întreruperii şi activarea rutinei de serviciu sau de răspuns corespunzătoare.
Am văzut ce este un program în limbaj maşină. Putem presupune că
execuţia unei instrucţiuni maşină nu poate fi întreruptă.
Prin starea unui program la un moment dat, notată prescurtat PSW
Program Status Word înţelegem o pereche formată din:
a) adresa următoarei instrucţiuni de executat;
b) conţinutul registrelor maşină la terminarea ultimei instrucţiuni.
Fiecare sursă posibilă a unei întreruperi are asociată o locaţie fixă de
memorie. În această locaţie se află o adresă care indică locul din memorie la
care se găseşte o secvenţă de instrucţiuni, numită handler, care deserveşte
întreruperea respectivă.
La apariţia semnalului de întrerupere, după ce instrucţiunea maşină în
curs s-a executat, se derulează în această ordine, următoarele activităţi:
a) se salvează într-o zonă de memorie (în stivă, sau o zonă prestabilită)
PSW-ul programului în curs de desfăşurare;
b) se restaurează PSW al handlerului asociat întreruperii;
c) handlerul execută acţiunile necesare deservirii întreruperii;
d) se salvează, numai dacă este necesară corelarea a două acţiuni
succesive ale aceluiaşi handler, PSW al handlerului;
e) se restaurează PSW al programului care a fost întrerupt.
Printre întreruperile care trebuie tratate la acest nivel se includ
întreruperile interne, provocate, de exemplu, de detectarea unei erori sau
127
printr-o acţiune care solicită trecerea în starea supervizor, ca şi toate
întreruperile externe.
Ca exemplu de acţiune care cauzează trecerea în starea supervizor se
poate cita cazul unui utilizator care încearcă să execute o instrucţiune
privilegiată sau caută să acceseze o informaţie protejată etc.
Dacă întreruperea implică o schimbare de alocare a procesorului, acest
modul al nucleului va activa dispecerul.
128
b) se produce o oarecare risipă de memorie, deoarece nu poate fi
prevăzută talia joburilor de executat şi rareori se va găsi un proces a
cărui talie să corespundă unei partiţii prestabilite.
program B program C
program E program G
program F program F
program G program G
129
Încărcare După un anu- Rearanjare
iniţială mit timp de prin relocare
funcţionare dinamică
Translatarea dinamică şi protecţia
În sistemele multiprogramate trebuie protejat fiecare program contra
eventualelor greşeli ale altor programe, greşeli susceptibile de a periclita
execuţia corectă a unui program prin posibilitatea de a pătrunde în zona sa
de memorie.
În principiu, este suficientă verificarea ca orice adresă calculată în timpul
execuţiei unui program să fie internă intervalului de adrese alocate
programului respectiv.
Această verificare se realizează cu ajutorul unui dispozitiv special care
compară adresa efectiv calculată cu adresele extreme ale zonei alocate
programului, stocate în registre „bornă“ sau mărginite (este necesar un
singur registru mărginit, deoarece adresa primei locaţii de memorie este
stocată în registrul de bază).
Pentru a găsi adresa referită se calculează adresa efectivă AE = baza +
dep şi se testează dacă baza AE sup.
Numai SO are dreptul să modifice conţinutul registrelor de bază şi al
celor mărginite, ceea ce implică instrucţiuni privilegiate care nu pot fi
executate decât în mod supervizor, iar dacă un program face referire la o
adresă din exteriorul bornelor sale, dispozitivul de verificare generează o
întrerupere alertând SO.
Figura următoare prezintă aceste mecanisme.
memorie
bază baza registru de bază
130
(lim. superioară)
Segmentarea
Segmentarea constă în divizarea unui program în module sau segmente,
fiecare segment corespunzând unei entităţi logice cum ar fi o procedură sau
un bloc de date, independentă de alte segmente.
Sistemul de operare se ocupă de plasarea în memorie a segmentelor
necesare execuţiei programelor gata să utilizeze CPU. Sistemul de operare
trebuie să ştie unde sunt stocate diferitele segmente, şi pentru aceasta el
organizează şi gestionează un ansamblu de tabele de segmente, câte o
tabelă pentru fiecare program, conţinând adresele de încărcare ale
segmentelor programului respectiv.
Adresa este structurată şi conţine 2 câmpuri:
a) numărul segmentului;
b) deplasamentul în cadrul segmentului.
131
Calculul adresei efective este realizat ca de obicei cu ajutorul unui
dispozitiv special, adăugând offsetul adresei de încărcare a segmentului care
este stocat în tabele de segmente.
Protecţia poate fi asigurată la nivelul tabelei de segmente adăugându-i
talia fiecărui segment sau ultima adresă a segmentului.
Memorie
Spaţiul de memorie Tabela de
al programului segmente 50K
(în memorie)
70K
0
Segment 1 Număr Poziţie 95K
20
1 50K
0 120K
Segment 2
25 2 95K 130K
0 145K
Segment 3 3 130K
15 155K
0 4 155K 165K
Segment 4
10
Paginare
Conceptul de paginare constă în a decupa cele două spaţii de adrese în
pagini de aceeaşi talie (1024 sau 2048 cuvinte) şi de a evidenţia un
mecanism de transfer de pagini între memoria virtuală şi cea reală.
În orice moment, un program gata de execuţie va avea plasate în
memorie câteva copii ale paginilor sale virtuale, alese în mod corespunzător
pentru a permite execuţiei sale să avanseze.
Sistemul de operare trebuie să rezolve câteva probleme importante:
a) dacă o anumită pagină se găseşte deja în memorie şi unde;
b) cum se convertesc adresele virtuale ale programului în adrese reale;
c) ce pagină va fi înlocuită pentru a face loc alteia;
d) cum se poate şti dacă pagina evacuată din memorie a fost modificată
şi trebuie deci recopiată în memoria auxiliară.
Tabela paginilor
Tabela paginilor constituie mecanismul esenţial care face să corespundă
fiecărei pagini virtuale o serie de informaţii, actualizate de către sistem. Un
bit indicator specifică prezenţa (sau absenţa) paginii în memoria principală.
Dacă pagina este în memoria principală, numărul paginii reale este
înscris în tabelă.
Un alt bit indică dacă pagina a fost modificată în timpul execuţiei.
Mecanismul de transformare a adreselor este următorul: câmpul de
adresă este divizat în două părţi:
a) numărul de pagină, singurul element care se modifică;
b) poziţia în cadrul paginii.
133
Tabela paginilor conţine de asemenea biţi de protecţie specificând un
anumit nivel al protecţiei (protejare în citire, scriere, execuţie etc.).
Tabela paginilor oferă de asemenea protecţia informaţiilor în sensul
apartenenţei adreselor la domeniul alocat paginii respective.
Paginarea la cerere
Această metodă de gestiune a memoriei constă în încărcarea unei pagini
din memoria virtuală numai dacă ea a fost referită.
Spaţiul de lucru
O alternativă a paginării la cerere constă în a plasa în memorie a unui
mic număr de pagini oportun selecţionate, acest ansamblu de pagini
numindu-se spaţiu de lucru.
Paginare şi segmentare
Anumite arhitecturi permit combinarea segmentării cu paginarea. Spaţiul
adreselor virtuale este segmentat şi segmentele sunt decupate în pagini.
Structura adresei trebuie să prevadă atunci trei câmpuri:
a) numărul segmentului ;
b) numărul paginii în cadrul segmentului;
c) deplasamentul în pagină.
Segmentarea fiind o divizare logică a spaţiului de adrese al programului,
este sarcina programatorului să definească segmentele. Paginarea este
realizată prin intermediul hardware-ului şi a sistemului de operare, ea este
deci transparentă pentru utilizator.
Organizarea intrărilor/ieşirilor
134
Intrările/ieşirile constituie domeniul cel mai delicat în concepţia şi
realizarea unui sistem de operare. Importanţa lor este fundamentală, dar
orice generalizare devine dificilă prin varietatea unităţilor periferice şi a
procedurilor de intrare/ieşire utilizate în sistemele de calcul actuale.
Dificultăţile se referă atât la aspectele materiale cât mai ales la
necesitatea de a asigura o gestiune optimală a resurselor sistemului precum şi
simplificarea sarcinii utilizatorilor acestuia.
Iată câteva aspecte ale problemelor care se ridică:
a) diversitatea funcţională a unităţilor periferice: imprimante laser,
unităţi de discuri magnetice şi optice, cartuşe magnetice etc.
b) diferenţa de viteză între unităţile periferice: de la câteva caractere
pe secundă ale tastaturii sau terminalului, la câteva milioane de
caractere într-o secundă pentru o unitate de discuri;
c) diversitatea de codificare şi structurare a informaţiilor
transferate: ASCII, EBCDIC, binar, cuvinte, octeţi, blocuri;
d) diferenţa între metodele de acces ale unităţilor: acces secvenţial
sau aleator, adresaj complet diferit pentru unităţile de bandă, discuri
sau mari memorii de arhivare;
e) diferenţa între condiţiile de partajare a perifericelor: o unitate de
discuri sau ecranul terminalului pot fi utilizate în acelaşi timp de
către mai multe procese, în timp ce o imprimantă nu poate fi
partajată decât în timp şi numai pentru job-uri întregi;
f) marea diversitate a condiţiilor de eroare: eroare de paritate,
imprimantă fără hârtie, eroare de poziţionare a unui cap de
citire/scriere pe disc, unitate deconectată, eroare de adresare etc.;
g) complexitatea sistemelor de legătură între periferice şi unitatea
centrală: DMA, canale, bus, unităţi de comandă, unităţi de
telecomunicaţii etc.;
h) gradul înalt de paralelism al operaţiilor;
i) necesitatea protejării utilizatorilor: „ascunderea” anumitor detalii
legate de operaţiile de intrare/ieşire;
j) necesitatea de a asigura independenţa programelor faţă de tipul
perifericelor utilizate.
Pentru rezolvarea acestor probleme, sistemul de operare încearcă să
trateze toate perifericele de o manieră uniformă (periferice virtuale,
codificare internă a caracterelor etc.), încredinţând toate prelucrările
particulare modulelor specializate, numite gestionari de unităţi periferce
device handlers, drivers.
Ca structură internă, acest nivel al sistemului de operare care se ocupă cu
gestiunea intrărilor/ieşirilor, se poate detalia pe subnivele, astfel:
135
a) proceduri standard (programe de bibliotecă) utilizate de către
aplicaţii şi conţinând cereri către supervizor;
b) un software de intrare/ieşire independent de unităţile periferice;
c) drivere, comandând fiecare unitate în detaliu;
d) programe de serviciu ale întreruperilor, acţionând în colaborare
cu funcţiunile nucleului.
Utilizatorul dispune de un set de instrucţiuni de intrare/ieşire virtuale,
spre deosebire de instrucţiunile de intrare/ieşire în cod maşină, specifice SO.
Instrucţiunile de intrare/ieşire virtuale se prezintă într-un limbaj de
programare evoluat sub forma unui apel de procedură sistem (read, write,
print etc), cu argumentele necesare de apel (nume variabile sau fişier, talie,
format, unitate logică etc.).
Aceste instrucţiuni sun înlocuite prin procedurile sistem corespunzătoare
în timpul fazei de compilare.
Există de asemenea probleme de protecţie la nivelul intrărilor/ieşirilor.
În acest context, sistemul de operare verifică corectitudinea convertirii
adreselor virtuale în adrese reale în momentul iniţializării, împiedicând
modificarea acestora înaintea terminării operaţiei de intrare/ieşire.
136
Sistemul de gestiune a fişierelor (SGF) este un ansamblu de rutine de
legătură între utilizatori şi componenta sistemului de intrare/ieşire la nivel
fizic pentru operarea cu fişiere. Utilizatorul dipune de o serie de operaţii
primitive pe care le poate solicita SGF-ului pentru serviciile dorite.
137
Tipuri de acces la articole
a) Accesul secvenţial la un articol f (i) presupune i - 1 accese în
ordine, la articolele cu numerele de ordine 1, 2, ..., i - 1.
b) Accesul direct random access presupune existenţa unui mecanism
de obţinere a articolului căutat fără a parcurge secvenţial toate
articolele care-l preced. Mecanismul de acces este de două feluri:
acesul direct prin număr de poziţie (adresă) are loc atunci când i
se furnizează SGF-ului o valoare i şi acesta returnează f (i)
(acces relativ);
prin conţinut, are loc atunci când i se furnizează SGF-ului o cheie (a,
v) şi acesta returnează acel articol i pentru care f (i). a = v.
Clasificarea fişierelor
a) După lungimea unui articol:
fişiere cu articole de format fix;
fişiere cu articole de format variabil.
b) După posibilitatea de afişare sau tipărire:
fişiere text al căror conţinut poate fi afişat pe ecran sau la
imprimantă;
fişiere binare, formate din şiruri de octeţi consecutivi, fără
nici-o semnificaţie pentru afişare.
c) După suportul pe care este rezident fişierul
fişiere pe disc magnetic;
fişiere pe bandă magnetică;
fişiere pe imprimantă;
fişiere tastatură;
fişiere pe ecran;
fişiere pe plotter, digitizor;
fişiere pe cartele perforate;
fişiere pe bandă de hârtie perforată.
d) După modurile de acces
fişiere secvenţiale;
fişiere în acces direct:
i) acces direct prin adresă;
ii) acces direct prin conţinut:
secvenţial-indexat;
selectiv;
multilistă;
B - arbore;
138
Referirea unui fişier
Utilizatorul se referă la un fişier în conformitate cu anumite reguli
sintactice impuse de către SO. În general, referirea la un fişier se face printr-
un şir de caractere, diferite de spaţiu. Şirul de referinţă conţine 5 zone,
plasate de la stânga la dreapta, astfel:
139
Descriptorul de fişier este un articol special care conţine informaţiile de
descriere ale unui fişier. Locul său de memorare este în directorul fişierului.
Apar patru grupe de informaţii:
a) identificarea fişierului (N, I), unde N este numele simbolic al
fişierului (specificatorul de fişier fără periferic), iar I este un număr
prin care descriptorul este reperat pe disc) în mod direct;
b) adresele fizice ocupate de fişier;
c) controlul accesului la fişier;
d) informaţii de organizare calendaristice.
Pentru controlul accesului la fişiere se foloseşte matricea de control
unde a (i, j)=1 dacă utilizatorul i are drept de acces la fişierul j, şi 0 în rest.
Clase de utilizatori:
a) proprietar: cel care crează fişierul şi stabileşte drepturi de acces la fişier;
b) utilizatori specificaţi: nominalizaţi de proprietar, cu statut special în
raport cu fişierul;
c) grup sau proiect: care pot folosi împreună un fişier;
d) public: restul utilizatorilor.
140
nivelul 3: fişier: numărul intrărilor este egal cu cel al
volumelor;
nivelul 2: volum: numărul intrărilor este egal cu numărul
cilindrilor din cadrul volumului;
nivelul 1: cilindru, conţine atâtea intrări câte pagini sunt în
cilindrul respectiv.
g) fişiere selective: au funcţia de regăsire materializată printr-un
calcul al CPU, numită funcţie de randomizare f : mulţimea
valorilor posibile pentru index0, 1, ..., n - 1 Articolele care au
aceeaşi valoare pentru funcţie se numesc sinonime.
h) fişiere organizate în B - arbori regulari. Fiecare nod este prevăzut
cu m căsuţe (pentru m chei unice). În fiecare nod pot fi maxim m şi
minim m div 2 chei. Înainte de prima cheie, între 2 chei şi după
ultima cheie sunt pointeri spre noduri subordonate.
Integritatea informaţiilor
Deoarece utilizatorul depinde de sistemul de fişiere pentru tot ceea ce
vizează aspecte legate de lucrul cu datele sale, este esenţial ca sistemul să fie
dotat cu mecanisme de salvare a informaţiilor permiţând eventual
reconstituirea fişierelor pierdute într-un accident software sau hardware.
Printre metodele comune utilizate în acest sens, sunt următoarele:
a) salvare completă backup, care permite recopierea pe bandă
magnetică a fişierelor disc, o dată la două sau trei zile. În caz de
accident, se pot reconstitui fişierele care existau în momentul
ultimului backup;
b) salvare incrementală, care permite recopierea doar a informaţiilor
modificate după ultimul backup. Această abordare permite reducerea
frecvenţei backup-urilor masive (de exemplu, o dată pe săptămână
141
sau pe lună). În cazul reconstrucţiei fişierelor, procedurile de lucru
sunt mai complexe;
c) dublarea sistematică a fişierelor disc, care constă în a păstra
întotdeauna două copii ale fiecărui fişier pe două unităţi de disc
diferite. Această metodă necesită mai puţine intervenţii din partea
operatorilor, dar implică dublarea spaţiului disc disponibil.
Servere de fişiere
O abordare modernă a gestiunii fişierelor, foarte la modă datorită
avântului informaticii distribuite, constă în a încredinţa unui calculator
independent întreaga gestiune a fişierelor specifice unei comunităţi de
utilizatori conectaţi la o reţea locală. Un astfel de calculator se numeşte
server de fişiere. În această arhitectură, partea majoră a spaţiului disc este
concentrată în jurul serverului, celelalte calculatoare din reţea nu au nevoie
de capacitate disc locală pentru fişierele lor.
O altă realizare recentă, datorată integrării tot mai pronunţate a
calculatoarelor şi a reţelelor este aceea a dispersate într-o reţea. Utilizatorul
unui astfel de sistem nu ştie şi nu are nevoie să ştie în care calculator sunt
stocate fişierele sale. În momentul în care o cerere de acces este adresată
sistemului de fişiere, acesta determină poziţia fişierului căutat şi, utilizând
serviciile reţelei, pune la dispoziţia solicitantului o copie a fişierului respectiv.
Alocarea resurselor
Într-un mod general, definim o resursă ca fiind un element necesar unui
procesor pentru a asigura execuţia sa în bune condiţiuni.
Resursele materiale ale unui sistem de calcul (CPU, memorii, dispozitive
de intrare/ieşire etc.), sunt disponibile în cantitate limitată şi trebuie să fie
partajate între diferite procese.
Produsele software şi fişierele, dacă pot fi partajate, fac de asemenea
parte dintre resursele pe care sistemul trebuie să le gestioneze.
Mecanismele de alocare ale unei resurse particulare sunt realizate pe
diferitele nivele ale sistemului de operare. De exemplu, dispecerul decide
dacă alocarea CPU şi alocarea unui fişier al unui proces este implementată la
nivelul gestiunii fişierelor.
Strategia de repartizare şi de alocare a resurselor trebuie să fie
determinată global, pentru tot sistemul. La nivelul sistemului, se iau decizii
în legătură cu planificarea globală a activităţii, se decide, de exemplu,
crearea de noi procese, sau aşteptarea, pe baza resurselor disponibile, nivelul
de prioritate al unui job.
Obiectivele acestui nivel al sistemului pot fi rezumate astfel:
142
a) asigurarea unei bune utilizări a resurselor: contabilizarea şi
furnizarea de statistici asupra resurselor principale;
b) crearea de noi procese şi atribuirea unui nivel de prioritate
corespunzător: se permite fiecărui proces existent în sistem să
obţină resursele necesare în limite de timp rezonabile;
c) excluderea mutuală a proceselor care solicită aceeaşi resursă
nepartajabilă şi şi evitarea situaţiilor de blocare (aşteptare fără
sfârşit a unei resurse de către mai multe procese).
Procesul sistem care se ocupă de toate aceste probleme se numeşte
planificator scheduler. Planificatorul determină ordinea de execuţie a job-
urilor lansate de utilizatori, el alege momentul pentru lansarea unei execuţii
şi refuză accesul unui utilizator interactiv dacă numărul de utilizatori
conectaţi poate conduce la o degradare inacceptabilă a timpului de răspuns.
Scopul planificatorului este de a asigura o exploatare echilibrată şi în
consecinţă un serviciu satisfăcător pentru toţi utilizatorii.
Interfaţa utilizator-sistem
Interfaţa între utilizator şi sistemul de operare se efectuează prin
intermediul unui limbaj, numit limbaj de comandă. Natura acestui limbaj
depinde de sistemul considerat.
Sistemele batch sunt dotate cu un limbaj relativ suplu şi puternic,
permiţând utilizatorului să specifice în avans succesiunea prelucrărilor de
realizat, ţinând cont de toate alternativele posibile.
Sistemele interactive oferă interfeţe mai simple prin care utilizatorul
poate urmări derularea job-ului său şi decide succesiunea operaţiilor pe
măsură ce se prezintă situaţiile posibile.
În majoritatea sistemelor actuale, modurile de lucru batch şi multiacces
coexistă, iar limbajul de comandă este adaptat în mod corespunzător.
Tendinţa actuală este de a simplifica sarcina utilizatorului, propunându-i
un repertoar de comenzi uşor de utilizat. Aceste comenzi se exprimă sub
forma cuvintelor cheie (Login, Logout, Edit, Fortran, Run, File, Copy,
Help etc.), urmate de anumiţi parametri. Este de asemenea normală
procedura de lucru prin care se realizează prescurtarea comenzilor (de
exemplu, fl în loc de file list) sau regruparea acestora în fişiere executabile,
un fel de macro-comenzi, de exemplu, se poate înlocui secvenţa Compile,
Link, Load, Run prin procedura Execute.
Directivele pe care utilizatorul le furnizează sistemului cu ajutorul
limbajului de comandă sunt interpretate de către interpretorul de comenzi
command interpreter. Acesta citeşte comenzile provenind de la terminal şi
după interpretarea acestora realizează serviciile solicitate. Datorită
143
dialogului, sistemul trebuie să semnaleze faptul că el „ascultă“ şi este gata să
primească instrucţiunile utilizatorului, răspunzând comenzilor şi
comunicând disponibilitatea sa prin afişarea pe ecran a unui caracter special
prompt, invitând utilizatorul de a formula noi cereri.
Comenzile trimise către sistem sunt o formă de cereri la supervizor
sistem calls, cu deosebirea că, în loc să provină dintr-un program sau
dintr-o procedură de bibliotecă, aceste comenzi sunt comunicate direct
sistemului de către utilizator.
Majoritatea limbajelor de comandă reflectă structura internă a sistemului
de operare, neputând fi schimbate decât cu mare greutate. Totuşi, în cazul
sistemului Unix, interpretorul de comenzi, numit shell, poate fi modificat sau
chiar înlocuit de către utilizator, care poate să comunice astfel cu sistemul
într-un limbaj convenabil ales.
Shell-ul interpretează comenzile provenind de la un terminal sau de la un
fişier shell script şi posedă structuri de control puternice, permiţând
execuţia condiţionată sau repetată a unei succesiuni de comenzi.
Cu abordarea shell, este uşor de a combina proceduri existente şi diverse
elemente de programare; adesea se utilizează shell-ul pentru a se evita
scrierea de noi programe.
144
8 SISTEMELE DE OPERARE ACTUALE
145
întrerupere prin care se realizează legătura cu toate unităţile
periferice conectate la sistem;
b) Componenta DISK-BIOS, este independentă de hardware-ul
sistemului de calcul şi ea extinde funcţiile ROM-BIOS. Această
componentă este materializată printr-un fişier disc care, în funcţie de
versiunea sistemului de operare poate avea unul dintre numele:
IBMBIO.COM, BIO.COM, IO.SYS, şi este rezidentă pe discheta
sau discul Wincester de pe care se încarcă sistemul. Funcţiile BIOS
care vizează a) şi b) au în vedere următoarele sarcini:
încărcare sistem de operare;
determinarea şi testarea echipamentelor periferice;
testarea memoriei RAM;
funcţii de bază asupra ecranului video;
funcţii elementare de citire a tastaturii;
funcţii elementare de lucru cu dischetele sau cu hard-discul;
funcţii de lucru cu caseta magnetică;
funcţii de lucru cu liniile de comunicaţie asincronă
(imprimantă, scanner, plotter etc.);
Pentru lucrul cu discul, BIOS operează cu cilindri, piste şi sectoare.
c) Componenta BDOS extinde funcţiile BIOS la un nivel mai înalt, în
special către lucrul cu discurile. Această componentă este
materializată printr-un fişier disc care, în funcţie de versiunea
sistemului de operare poate avea unul dintre numele:
IBMDOS.COM, DOS.COM, MSDOS.SYS, şi este rezidentă pe
discheta sau discul Wincester de pe care se încarcă sistemul. Cele
mai importante sarcini BDOS sunt următoarele:
gestiunea memoriei: alocarea şi eliberarea spaţiului de memorie
necesar programelor;
gestiunea proceselor (programelor);
execuţia operaţiilor de intrare/ieşire cu periferice de tip caracter;
tratarea fişierelor disc: creare, deschidere, închidere, accesare,
ştergere;
partajarea fişierelor între mai multe procese active la un
moment dat;
gestiunea structurii arborescente a fişierelor şi manipularea
directoarelor ;
gestiunea reţelelor de calculatoare;
modificări ale sistemului de întrerupere;
gestiunea ceasului intern şi a calendarului.
146
d) Componenta COMMAND are ca sarcină principală preluarea
comenzilor formulate de utilizator de la tastatură şi lansarea lor în
execuţie. Această componentă este materializată prin fişierul disc
COMMAND.COM. Comenzile DOS sunt de două tipuri:
comenzi interne, înglobate în COMMAND şi încărcate permanent
în memorie. De regulă, acestea sunt comenzi mai simple şi de primă
utilitate: rezumate de disc, copieri de fişiere etc.
comenzi externe, rezidente pe disc sub forma unor programe
executabile sau sub forma unor fişiere de comenzi (fişiere text
în care sunt apelate alte comenzi DOS). De regulă, comenzile
externe sunt mai complexe decât cele interne.
În timpul introducerii comenzilor, DOS recunoaşte o serie de funcţii de
control, din care amintim câteva:
<CTRL/C> sau <CTRL/Break>: abandonează linia de comandă;
<F3>: copiază pe ecran ultima linie introdusă;
<CTRL/P>: trimite în ecou ieşirea pe ecran şi imprimantă;
<CTRL/N>: anulează efectul lui <CTRL/P>;
<CTRL/S>: opreşte temporar defilarea ecranului, repornirea se
realizează prin apăsarea oricărei taste cu excepţia <CTRL/C>;
<F6> sau <CTRL/Z>: inserează marcator de sfârşit fişier;
<F1>: copiază un caracter din şablon şi îl afişează;
<F2>: copiază toate caracterele care preced un caracter specificat.
Generarea sistemului de operare DOS pe o dischetă sau pe un hard-disc se
realizează prin intermediul unor comenzi standard, ştergând toate informaţiile
vechi de pe discul respectiv. Etapele generării unui disc DOS sunt următoarele:
a) Partajarea hard-discului: împărţirea în una până la patru zone
contigue numite partiţii. În acest fel, în loc de un singur disc mare,
DOS „vede” mai multe discuri mici. Operaţia de partajare se
realizează cu ajutorul programului FDISK, care printr-un dialog cu
utilizatorul realizează partiţionarea la dimensiunile dorite;
b) Formatarea discului. Comanda DOS FORMAT realizează
formatarea discului (împărţire în cilindri, piste, sectoare) şi
verificarea sectoarelor sale. Tot prin această comandă se crează
discul sistem DOS (opţiunea /S), iar ca efect, pe discul respectiv se
realizează următoarele:
în sectorul 0 se pune programul bootstrap de încărcare a
sistemului de operare;
se depun pe disc fişierele IBMBIO.COM, IBMDOS.COM şi
COMMAND.COM;
în restul sectoarelor se pune valoarea 0.
147
Dacă s-a procedat la partajarea hard-discului este necesară formatarea
tuturor unităţilor de disc logic care au ca suport fizic discul partajat.
Este suficientă formatarea cu opţiunea „/S” numai a uneia dintre
partiţii (cea care este declarată activă prin FDISK);
c) Crearea fişierului de configurare. La fiecare lansare a sistemului
se execută o operaţie de configurare prin care se fixează valorile
unor parametri sistem, cum ar fi:
numărul fişierelor deschise simultan;
numărul zonelor tampon pentru operaţiile de intrare/ieşire;
numărul şi dimensiunea stivelor;
condiţia de sesizare a tastării <CTRL/Break>;
convenţiile de ţară, timp, monedă;
precizarea unor noi drivere de intrare/ieşire;
Aceşti parametri sunt precizaţi prin intermediul unui fişier text numit
CONFIG.SYS. Dacă fişierul nu este prezent pe disc, atunci DOS
atribuie acestor parametri nişte valori implicite, care depind de tipul
sistemului de calcul. De obicei, conţinutul acestui fişier este stabilit
la generare în funcţie de configuraţia hardware şi de aplicaţiile care
vor fi rulate pe sistemul respectiv. Fişierul se crează simplu, cu
ajutorul unui editor de texte, eventual el poate fi pregătit dinainte,
urmând a fi copiat pe noul disc;
d) Crearea fişierului de comenzi iniţiale. În momentul lansării
sistemului, după fixarea parametrilor de configurare şi după
încărcarea interpretorului de comenzi, DOS caută pe disc un fişier
cu numele AUTOEXEC.BAT. Acesta este un fişier text în care
utilzatorul trece toate comenzile DOS care se doresc a fi executate la
lansarea sistemului. De obicei, aceste comenzi se referă la:
fixarea de către utilizator a datei şi orei exacte de pornire;
fixarea modului de afişare a prompterului de invitare la comenzi;
precizarea directoarelor de pe disc unde DOS caută comenzile
externe.
La fel ca şi CONFIG.SYS, fişierul AUTOEXEC.BAT poate fi
pregătit (eventual în avans) folosind un editor de texte.
e) Copierea fişierelor dorite pe discul sistem. Se realizează cu
comanda XCOPY.
Sistemul DOS dispune de comanda internă SELECT destinată realizării
automate a ultimelor 3 etape.
148
Sistemul de operare DOS, începând cu versiunea 2.0 adoptă un sistem de
fişiere organizat arborescent. În forma cea mai simplă, un fişier obişnuit se
specifică astfel: nume. tip, unde nume are maximum 8 caractere, iar tip are
maximum 3 caractere.
Fişierele speciale DOS au nume predefinite, care nu pot fi utilizate ca
nume pentru fişierele obişnuite. Numele rezervate sunt:
CON desemnează tastatura, dacă este folosit ca fişier de intrare,
respectiv ecranul terminalului, dacă este folosit ca fişier de ieşire;
PRN (având ca sinonim LPT1), LPT2, LPT3 desemnează una dintre
imprimantele paralele;
AUX (având ca sinonim COM1), COM2, COM3 şi COM4
desemnează unul dintre adaptoarele de comunicaţii asincrone);
NUL este numele unui fişier (echipament) fictiv. Folosit ca fişier de
intrare generează imediat pentru sistemul de gestiune a fişierelor
marcatorul de sfârşit de fişier, iar folosit ca fişier de ieşire,
informaţiile „scrise” în el nu sunt de fapt depuse nicăieri.
În forma cea mai generală, un fişier pe suport disc se specifică prin cele
patru zone, adică: periferic cale nume .tip, unde:
perferic se va specifica printr-o literă urmată obligatoriu de „:”.
DOS poate avea maximum 26 de periferice de tip disc notate cu
literele alfabetului, începând cu A. În mod obligatoriu literele A: şi
B: desemnează dischete. Dacă sistemul de calcul dispune de hard
disc el (primul dintre ele) va fi notat cu C:, apoi pot urma şi alte
periferice de tip disc. Dacă lipseşte specificarea pentru periferic,
sistemul presupune că este vorba despre perifericul implicit;
cale indică, după caz, succesiunea directoarelor de la rădăcină până
la fişier (primul simbol din cale este „\“) sau de la directorul curent
până la fişier (când cale nu începe cu „\“). Separarea directoarelor
DOS se face cu simbolul „\“. Dacă specificarea de cale lipseşte,
atunci sistemul consideră că fişierul face parte din directorul
curent. Sistemul DOS reţine câte un director curent pentru fiecare
periferic disc din sistem şi de aceea, atunci când se trece de la un
periferic la altul fără să i se indice acestuia calea, sistemul consideră
că este vorba despre directorul curent al perifericului respectiv.
tip poate lipsi, dar în general se foloseşte pentru a indica conţinutul
fişierului. Câteva tipuri sunt uzuale: BAS, FOR, PAS, C, ASM, OBJ,
EXE, COM, BAT, LST, DAT, DOC, TXT, MAP, LIB, TMP, BAK.
Unele comenzi DOS acceptă specificarea generică a unei familii de fişiere.
Aceasta presupune folosirea, numai în zona de nume sau tip (eventual în
149
ambele) a simbolurilor speciale: „*”, care poate substitui un grup de caractere,
sau „?”, care poate substitui un caracter pe poziţia pe care se găseşte.
Iată câteva exemple de nume de fişiere:
PROG.PAS, PROG;
B: ALFA. UNU, B: ALBA. DOI, B: ALGA. COM;
C: \ programe\ pascal\ *. PAS
Primele două fişiere se află pe perifericul implicit şi în directorul curent.
Următoarele trei fişiere sunt pe discul B: şi în directorul implicit.
Specificarea generică PROG.* include primele două fişiere. Specificarea B:
AL?A.* conţine cele trei fişiere de pe discul B:.
Specificarea C: \ programe\ pascal\ *. PAS conţine toate textele sursă Pascal
aflate în directorul numit pascal, care este subdirector al directorului programe,
care este subdirector al rădăcinii discului C:. Dacă directorul curent este
\programe, atunci specificarea poate fi făcută şi sub forma C: \ pascal\ *. PAS.
150
a) Zona de boot conţine informaţii care sunt utilizatecând se încarcă
sistemul de operare. Aceste informaţii sunt dependente de sistem,
dar în mod tipic conţin un program de încărcare;
b) FAT - Tabela de alocare a fişierelor conţine informaţii cu ajutorul
cărora se gestionează spaţiul pe disc. În FAT este înregistrată starea
zonelor de pe disc divizate în entităţi numite clustere. Pentru a
cunoaşte lungimea unui cluster indiferent de disc se va specifica
comanda CHKDSK. Alocarea clusterelor se realizează prin
intermediul FAT care conţine o listă de numere care reprezintă
fiecare cluster alocat pe disc:
dacă intrarea în FAT este 0, atunci clusterul este liber;
dacă intrarea în FAT este nenulă, atunci este un cluster în
folosinţă, iar numărul găsit este utilizat pentru a lega diferite
clustere care alcătuiesc împreună fişierul;
FAT
4 5 7 8 EMPTY
cluster
2 3 4 5 6 7 8
c) ROOT directory - directorul rădăcină, simbolizat prin „ \ “ este
un director în care se memorează, pentru fiecare fişier următoarele
infirmaţii:
numele şi extensia sa;
data creării sau a modificării (vizibile cu comanda DIR);
numărul de început al clusterului (clusterul care conţine prima
înregistrare a fişierului);
atributul fişierului;
d) File - Zona alocată fişierelor conţine în prima parte fişierele
sistemului de operare IBMBIO. COM şi IBMDOS. COM şi în
continuare, fişierele divizate în clustere a căror ordine de legături
este păstrată în FAT. Subdirectorii sunt localizaţi în FAT ca orice alt
fişier, iar atunci când se utilizează conţinutul unui subdirector, acesta
acţionează ca şi directorul rădăcină.
151
directoarelor curente de pe fiecare disc şi în plus, efectuează un număr de
comenzi DOS prestabilite.
Comenzile DOS se împart în două categorii:
a) comenzi rezidente (interne), sunt comenzile înglobate în
COMMAND. COM;
b) comenzi tranzitorii (externe), sunt cele care solicită existenţa pe
disc a unui fişier de tip .COM sau .EXE având ca nume numele
comenzii.
O comandă rezidentă se lansează astfel: ... > comanda argumente, iar o
comandă rezidentă: ... > comanda d: cale argumente.
Ca efect, COMMAND.COM caută şi reperează pe disc un fişier având
unul din numele: comanda.COM, comanda.EXE, comanda.BAT
Dacă se specifică „d:”, atunci căutarea se face pe discul specificat, în caz
contrar se caută pe discul implicit.
Dacă se specifică „cale”, atunci fişierul se caută în directorul indicat de cale.
În situaţia în care lipseşte atât specificarea de disc cât şi specificarea de
cale, căutarea se face în ordine:
în directorul curent;
în directoarele specificate prin comanda PATH.
În cazul în care, în acelaşi director este reperat mai mult de un fişier din
cele trei, de exemplu, unul de tip COM şi altul de tip BAT, prioritatea la
lansare o are COM, apoi EXE şi la urmă BAT.
O sinteză a formatului comenzilor DOS cu principalele opţiuni este
prezentată în figura următoare. Comenzile interne sunt evidenţiate prin litera
„I” plasată în dreapta comenzii.
CD d:cale sau CHDIR d:cale I
MD d:cale sau MKDIR d:cale I
RD d:cale sau RMDIR d:cale I
JOIN d1 d2 \director /D
FDISK d:
FORMAT d: /S/V
UNFORMAT d:
LABEL d:etichetă_volum
DISKCOMP d1: d2:
DISKCOPY d1: d2:
CHKDSK d:calefişier. tip/F/V
RECOVER d:
DIR d:calefişier. tip/P/W I
COPY /A/Bd:calefişier. tip
+d:calefişier.tip...d:calefişier.tip I
152
XCOPY d:calefişier. tip d:calefişier. tip
/A/D: ll-zz-aa/E/M/P/S/V/W
REN sau RENAME d:calefişier.tip d:calefişier.tip I
DEL sau ERASE d:calefişier.tip I
UNDELETE d:calefişier.tip/LIST/ALL
COMP d:calefişier.tip d:calefişier.tip
TYPE d:calefişier.tip I
PRINT d:calefişier.tip ... /C/P/T
SORT /R/+n
FIND /V/C/N „şir” sau d:calefişier.tip ...
MORE
EXE2BIN d:calefişier. COM d:calefişier. EXE
PATH d:cale;d:cale ... I
APPEND d:cale;d:cale ...
FASTOPEN d: = n
DATE ll-zz-aa I
TIME hh-mm:ss I
BREAK ONOFF I
PROMPT text I
SET nume = valoare I
CLS
MEM /P/C/D
VER I
VOL d: I
HELP comanda
153
„/D” realizează operaţia inversă, adică deconectarea, iar atunci
se vor specifica numai „d1” şi „/D”;
154
c) Comenzi referitoare la fişiere:
DIR: listează toate intrările din fişierul director sau numai cele
specificate. Parametrul „/P” generează execuţia unei pauze ori
de câte ori ecranul este plin de informaţii, iar parametrul „/W”
produce o afişare condensată a directorului, listând doar
numele fişierelor, câte cinci nume pe linie;
COPY: copiază unul sau mai multe fişiere pe un alt disc şi
opţional, atribuie un nume diferit pentru copie. De asemenea,
COPY poate crea o copie pe acelaşi disc. În timpul procesului
de copiere se poate realiza şi o concatenare de fişiere, dacă se
specifică operatorul „+”. Parametrii „/A” şi „/B” indică
volumul de date care se va copia şi anume:
- în intrare: „/A” exclude copierea marcatorului de sfârşit de
fişier, iar „/B” impune copierea întregului fişier;
- în ieşire: „/A” adaugă marcatorul de sfârşit de fişier, iar „/B”
nu adaugă marcatorul de sfârşit de fişier;
XCOPY: permite copierea selectivă de fişiere sau grupuri de
fişiere care pot să includă şi subdirectoare. Ca opţiuni, pot fi:
- „/A”: copierea fişierelor marcate pentru arhivare;
- „/M”: identic cu „/A”, dar schimbă marcajul de arhivare;
- „/D”: copierea fişierelor modificate după data specificată;
- „/E”: crează la destinaţie subdirectoarele din sursă;
- „/P”: copierea cu confirmare pentru fiecare fişier;
- „/S”: copierea din sursă a directoarelor şi subdirectoarelor
- „/V”:verificare scriere la destinaţie (recitire şi comparare)
REN (RENAME): schimbă numele fişierului specificat;
DEL (ERASE): şterge fişierul cu numele specificat, din
directorul şi unitatea specificate sau implicite;
UNDELETE: permite refacerea fişierelor şterse (valabilă la DOS
5.0). În mod obişnuit se reface un singur fişier, dar opţiunea
„/ALL” permite refacerea tuturor fişierelor posibile, caz în care
prima literă a numelor acestor fişiere este stabilită automat.
Opţiunea „/LIST” permite afişarea fişierelor care pot fi refăcute;
COMP: compară două fişiere de aceeaşi lungime, prin citirea şi
compararea conţinutului lor. Compararea se termină fie la sfârşit,
fie la depistarea a maximum 10 octeţi diferiţi ( primele 10
diferenţe sunt afişate);
TYPE: afişează conţinutul fişierului specificat pe dispozitivul
standard de ieşire;
155
PRINT: tipăreşte o coadă (listă) de fişiere de date la imprimantă
în timp ce pe sistem se pot executa alte lucrări;
d) Filtre DOS:
SORT: citeşte date de la echipamentul standard de intrare,
sortează datele, apoi scrie datele sortate la echipamentul
standard de ieşire. Sortarea se efectuează crescător după
codurile ASCII ale caracterelor, sau descrescător („/R”);
FIND: trimite la echipamentul standard de ieşire toate liniile din
fişierul specificat în comandă şi care conţin un şir de caractere
specificat. Parametrul „/V” determină afişarea tuturor liniilor
care nu conţin şirul specificat, iar parametrul „/C” permite
afişarea unui contor cu numărul de apariţii a şirului specificat;
MORE: este un filtru care citeşte date de la intrarea standard şi
le transpune pe ecran, iar când acesta este plin, se aşteaptă
apăsarea unei taste pentru a se trece la ecranul următor;
EXE2BIN: este un filtru special care transformă un program
executabil de tip EXE în unul de tip COM;
f) Comenzi de informare:
MEM: afişează conţinutul memoriei la un moment dat;
VER: afişează versiunea sistemului de operare DOS;
VOL: afişează eticheta de volum specificat sau a celui curent;
HELP: oferă detalii despre comenzile DOS în general, sau
despre o anumită comandă DOS specificată.
156
Fişiere de comenzi (BAT) sub DOS
Un fişier de comenzi (al cărui tip este . BAT), este un fişier text care
conţine una sau mai multe comenzi şi/sau directive care se execută succesiv,
fără intervenţia directă a utilizatorului. Un prim exemplu de fişier de
comenzi DOS este fişierul AUTOEXEC. BAT. Dacă acest fişier este prezent
în directorul rădăcină pe discul de pe care se face încărcarea, DOS execută
automat comenzile din el la fiecare încărcare a sistemului.
Un fişier de comenzi DOS conţine mai multe tipuri de construcţii:
- comenzi DOS propriu-zise;
- etichete;
- caracterele speciale , <, > şi %;
- parametrii formali care vor fi înlocuiţi la lansare cei actuali;
- variabile globale rezidente în interpretorul de comenzi;
- variabile locale utilizate în instrucţiuni repetitive;
- directive adresate interpretorului fişierelor de comenzi.
Exemplu: TIPAR. DAT: DIR *. PAS
COPY *. PAS a:
DEL *. PAS
O etichetă se scrie sub forma: : nume, unde caracterul „:” este urmat de
maximum 8 litere sau cifre. O etichetă apare pe o singură linie, la început de rînd.
Caracterele speciale , < şi > sunt interpretate în comenzi prin legare în
pipe a două comenzi, respectiv redirectarea intrării şi/sau ieşirii standard a
unei comenzi.
Caracterul % marchează parametrii formali, variabilele globale şi
variabilele locale.
Într-un fişier de comenzi pot fi specificaţi până la 10 parametri formali,
notaţi %0, %1, ..., &9. Corespunzător acestora, în linia de comandă care
lansează în execuţie fişierul de comenzi argumentele sunt puse în
corespondenţă cu aceşti parametri.
De exemplu, în figura următoare este dat un fişier de comenzi care
compilează două programe Fortran şi le leagă într-un fişier executabil.
Primele două argumente dau numele celor două texte sursă, iar al treilea
numele programului executabil.
Dacă se lansează fişierul prin comanda: ... FORTR XAA YBB REZ
atunci parametrii formali vor avea valorile:
%0 FORTR;
%1 XAA;
%2 YBB;
%3 REZ.
157
FORTR. BAT: WS %1. FTN
FOR %1, %1, %1
PH2 %1
WS %2.FTN
FOR %2, %2, %2
PH2 %2
LINK %1+ %2, %3, FORTRAN
DEL %1. BAK
DEL %1. OBJ
DEL %2. BAK
DEL %2. OBJ
158
Directiva IF permite execuţia condiţionată a unei comenzi DOS din
fişierul de comenzi, sau a unei alte directive.
Fiecare comandă DOS transmite, în momentul terminării, un cod cu o
valoare între 0 şi 255. De obicei, un cod cu o valoare nenulă indică o situaţie
neobişnuită, în anumite situaţii de programare specificând ramura pe care s-a
terminat programul. Condiţia „ERRORLEVEL număr” este adevărată
dacă codul de retur al ultimei comenzi este mai mare sau egal cu numărul
scris după cuvântul ERRORLEVEL.
Condiţia „şir1 == şir2” este adevărată dacă valorile celor două şiruri de
caractere coincid, iar cel puţin unul din şiruri trebuie să conţină un parametru
formal sau o variabilă globală.
Condiţia „EXIST fişier” este adevărată dacă fişierul specificat, simplu
sau generic există.
Acţiunea directivei IF fără NOT înseamnă execuţia comenzii dacă
condiţia este adevărată, iar dacă NOT este prezent, atunci comanda se
execută când condiţia este falsă.
Comanda ASK face parte dintr-o familie de programe utilitare oferite de
firma NORTON. Prin intermediul acestei comenzi, utilizatorul poate
interacţiona cu fişierul de comenzi.
ASK mesaj, litere are ca efect afişarea pe ecran a „mesaj”, care nu
conţine „,”, după care aşteaptă ca utilizatorul să apese una din literele dintre
paranteze . Dacă utilizatorul a tastat a i-a literă din listă, atunci ASK se
termină cu ERRORLEVEL = i. Evident, o succesiune de directive IF poate
realiza o ramificare multiplă a execuţiei.
159
DEL %0
GOTO :IAR
:STOP
Lansat cu ...> STERGE a b c d e f g h i j k l va şterge pe rând cele 12
fişiere citate în comandă.
Directiva ECHO permite să se afişeze (ON) sau să nu se afişeze (OFF)
comenzile care se execută, sau dacă directiva conţine un mesaj, se afişează
acest mesaj pe ecran.
Directiva PAUSE suspendă execuţia fişierului de comenzi până la
apăsarea unei taste.
Întreruperea execuţiei unui fişier de comenzi se face cu <CTRL/C>.
160
Fişier curent Left Fişier curent Right
D: \CURENT>
161
după lungimea fişierului (primul va fi cel mai lung);
după apariţia fizică în director (nesortate).
Se pot realiza schimbări de director sau disc, astfel:
schimbarea discului se realizează prin meniu cu <ALT/F1>, pentru
fereastra Left şi cu <ALT/F2> pentru Right;
schimbarea de director se realizează fie cu comanda DOS CD, fie
tastând <ENTER> din aproape în aproape până la directorul dorit;
filtrările de fişiere cu FILTER furnizează informaţii despre:
- toate fişierele;
- numai cele executabile (COM, EXE, BAT);
- cele cerute cu o specificare generică.
162
Compare directory: comparare de directoare din punct de
vedere al conţinutului şi al datei de creare. Ca efect al comparării se
marchează fişierele dintr-o fereastră care nu sunt în cealată fereastră
sau fişierele dintr-o fereastră care sunt mai recente decât cele
omonime din cealaltă;
Menu file edit: crează meniuri utilizator;
Extension file edit: defineşte în mod automat nişte acţiuni cu fişiere
de un anumit tip, de exemplu, şterge automat dacă se tastează
<ENTER> pe un fişier curent de tip BAK, lansează Turbo Pascal pe
un fişier curent de tip PAS etc.
163
sistemul de operare DOS dar Windows ’95 a devenit un sistem de operare care
nu mai are nevoie de un sistem DOS preinstalat, fiindcă de fapt încorporează
facilităţile acestuia (versiunea 7 a sistemului DOS), oferind utilizatorului diverse
servicii într-o formă nouă, cu o interfaţă vizuală, intuitivă. Totuşi, dezvoltarea
succesivă a versiunilor de Windows a urmărit cu consecvenţă principiul
compatibilităţii cu versiunile anterioare.
Sistemele Windows 3.0 şi 3.1 adaugă la serviciile oferite de sistemul de
operare DOS un mediu de operare grafic, cu facilităţi de multitasking. În
cazul în care o aplicaţie defectuoasă scrie în zona sistemului de operare sau a
altei aplicaţii, apare eroarea „General Protection Fault”.
Facilitatea de multitasking a sistemului Windows exploatează posibilităţile
microprocesoarelor Intel, care o oferă începând cu 80286, prin modul de lucru
protejat. În acelasi timp, le este permis utilizatorilor accesul la memoria extinsă.
Aceste sisteme lucrează pe 16 biţi, ceea ce nu este convenabil pentru memorarea
structurilor de date de dimensiuni mari. O dată cu trecerea la microprocesoare pe 32
de biţi, se încearcă trecerea la gestiunea memoriei pe 32 de biţi, care va aduce
creşterea considerabilă a performanţelor (se diminuează riscul de a nu putea folosi
memorie din cauza dimensiunii reduse a segmentelor de memorie adresabile pe 16
biţi). În acest scop, se introduc două instrumente: o bibliotecă dinamică de funcţii
(Dynamic Link Library - DLL), numită WINMEM32, care permite programatorilor
să scrie cod pentru Windows 3.0 folosind un spaţiu adresabil de 32 de biţi şi o
interfaţă de programare a lui Windows 3.1, numită WIN32s, care facilitează trecerea
spre Windows NT şi Windows ’95.
Windows 3.1 nu oferă suport de reţea, nu are clienţi de reţea integraţi dar
se poate executa pe un calculator dintr-o reţea Novell Netware, folosind
serviciile oferite de aceasta. (Windows 3.1 se poate instala într-o
configuraţie de reţea astfel încât în reţea să existe un singur exemplar,
partajabil, al sistemului iar pe staţia client să fie instalată o configuraţie
minimală, de aproximativ 300KB.)
Sistemul Windows 3.1 necesită, ca şi configuraţie hard minimală, un
procesor 80286 cu 1MB RAM dar se recomandă a se folosi un
microprocesor 80386 cu 4 MB RAM.
Windows for Workgroups 3.11 a apărut din necesitatea introducerii
suportului de reţea pentru sistemul de programe Windows. Suportul de reţea
oferit de Windows for Workgroups 3.11 (numit suport „punct la punct”)
permite partajarea resurselor unui calculator cu alţi utilizatori aflaţi în acelasi
grup de lucru. Se pot folosi eventual facilităţile unui server de reţea mai
complex (Novell Netware sau Windows NT).
Interfaţa cu utilizatorul este foarte asemănătoare cu Windows 3.1. În plus,
apare un grup de aplicaţii de reţea - Network - şi posibilitatea de a folosi un sistem
164
de mail. Se introduce o versiune îmbunătăţită a lui Clipboard Viewer, numită
Clipbook.
Pentru îmbunătăţirea accesului la disc se scrie un driver virtual de 32 de
biţi (VD) care creşte viteza de acces la resursele de reţea cu 100% şi viteza
de acces la datele de pe hard-disk cu 50% fată de Windows 3.1.
Configuraţia fizică minimală necesară lui Windows for Workgroups este
un microprocesor 80386 cu 4 MB RAM dar se recomandă 8 MB RAM.
Windows NT are două versiuni: pentru staţie de lucru (Microsoft
Windows NT Workstation) şi pentru server de reţea (Microsoft Windows
NT Advanced Server). Windows NT este un sistem de operare de tip server
de aplicaţii, adică oferă un suport puternic pentru crearea de aplicaţii
distribuite, bazate pe comunicarea client-server. De aceea, el va fi folosit cu
succes de firmele care produc sisteme de gestiune a bazelor de date.
Windows NT are numeroase îmbunătăţiri pentru utilizarea pe staţii de
lucru şi oferă mecanisme performante care asigură partajarea şi securitatea
informaţiilor. Iniţial, interfaţa cu utilizatorul a păstrat stilul Windows 3.1 dar
ulterior au apărut versiuni în stilul Windows ’95
Enumerăm în continuare caracteristicile sistemului Windows NT:
este primul sistem de operare Windows (nu are nevoie de o copie
preinstalată DOS pentru a se lansa în execuţie);
lucrează pe 32 de biţi şi oferă un mecanism de multitasking mai
performant decât predecesoarele lui;
oferă un nou sistem de fişiere (NTFS) şi portabilitate pe procesoare non-
Intel;
sistemul de securitate şi siguranţa în funcţionare constituie cea mai
importantă caracteristică a lui Windows NT. Arhitectura să oferă cea
mai bună protecţie în comparaţie cu alte sisteme de operare noi: OS/2
sau Windows ’95. Protecţia absolută a datelor şi aplicaţiilor este mai
importantă decât viteza şi principiul compatibilităţii (este incompatibil
cu anumite programe rezidente DOS);
oferă facilităţi pentru utilizarea în reţea;
nu are mecanismul "Plug and Play" al lui Windows ’95 (care va fi
descris mai jos) dar oferă drivere pentru majoritatea dispozitivelor
hard care ar putea fi utilizate, cu o configurare simplă.
Necesarul de memorie pentru lansarea lui Windows NT este mult mai mare
decât al celorlalte sisteme: minumum 12 MB RAM dar devine foarte competitiv la
32 MB RAM. Este un sistem costisitor dar oferă stabilitate şi protecţie.
Windows ’95 este un sistem de operare pe 32 de biţi (nu are nevoie de
MS-DOS pentru a se lansa în execuţie) care permite execuţia de aplicaţii
multithreading (cu mai multe „fire” de execuţie, care funcţionează în regim
165
de multitasking). Stilul de execuţie al aplicaţiilor DOS, pe 16 biţi şi pe 32 de
biţi este similar cu cel de sub Windows NT. Aplicaţiile native Windows ’95
sunt foarte rapide dar la Windows ’95 se pot adapta relativ uşor aplicaţii
Windows 3.1 (folosind interfaţa WIN32) şi mai ales aplicaţii Windows NT.
Un principiu de bază urmărit în proiectarea lui Windows ’95 a fost
compatibilitatea cu versiunile mai vechi: se pot executa aplicaţii MS-DOS şi
Windows pe 16 biţi, ceea ce lărgeşte semnificativ numărul de aplicaţii pe
care le pune la dispoziţia utilizatorului, oferindu-i un avantaj considerabil
faţă de alte sisteme de operare (OS/2, Unix sau Windows NT).
Interfaţa lui Windows ’95 are caracteristici proprii sistemelor orientate
obiect: la lansare apare un desktop cu diverse icon-uri, aplicaţiile care se
execută apar în bara de task-uri şi pot fi manipulate într-un mod foarte
intuitiv, folosit prima oară la Apple MacIntosh şi preluat de OS/2 Warp. În
plus, fiecărui obiect îi este asociat un meniu numit contextual, care conţine
operaţii uzuale şi poate fi accesat cu butonul din dreapta al mouse-ului.
Windows ’95 introduce un nou sistem de fişiere, prin care se pot folosi
nume de maximum 255 de caractere. Creşte calitatea şi numărul accesoriilor:
Notepad şi Character Map rămân dar Write este înlocuit cu WordPad,
Paintbrush - cu Paint, Calculator este îmbunătăţit, Calendar şi Cardfile dispar
dar apare Briefcase. Se aduc îmbunătăţiri şi în privinţa comunicărilor prin
introducerea aplicaţiei Exchange, care interacţionează cu Microsoft Mail,
Microsoft Exchange Server şi Microsoft Network.
Din punctul de vedere al posibilităţilor oferite pentru lucrul în reţea, se
remarcă faptul că Windows ’95 are o suită importantă de protocoale de reţea
(IPX/SPX, NetBEUI şi TCP/IP, care face posibilă comunicarea în Internet) şi de
drivere pentru plăcile de reţea. Accesarea calculatoarelor din reţea este foarte
uşoară folosind Network Neighborhood. Calculatorul poate lucra ca serviciu
telefonic de răspuns automat şi poate contabiliza apelurile telefonice prin interfaţa
de telefonie Microsoft.
Încadrarea facilităţilor lui Windows ’95 în noile direcţii de dezvoltare a
aplicaţiilor multimedia se realizează prin intermediul bibliotecii WinG, care
permite crearea de aplicaţii grafice cu performanţe superioare şi a interfeţei
de programare WinToon, pentru grafică şi animaţie multimedia.
Una din cele mai utile şi ambiţioase caracteristici a lui Windows ’95 este
facilitatea „Plug and Play”: prin încorporarea unui număr impresionant de
drivere, un număr mare de periferice este implicit instalat, astfel încât acestea pot
fi utilizate direct.
Necesarul hard minimal pentru Windows ’95 este un microprocesor
80386DX cu 4MB RAM dar se recomandă cel puţin un microprocesor
80486 pe 33MHz cu 8MB RAM iar pentru a executa aplicaţii simultane -
166
16MB RAM şi 75MB liberi pe hard-disk. Testele efectuate au arătat că
Windows ’95 se execută ceva mai încet decât Windows for Workgroups
3.11 pe 4MB RAM dar se comportă similar sau mai bine pe cel puţin 8MB
RAM. Windows ’95 rulează grafica mai rapid şi are accesul la disc mai lent
decât Windows for Workgroups 3.11 dar este foarte rapid şi stabil pentru
aplicaţiile native de 32 de biţi.
Windows ’98 are caracteristici similare cu Windows ’95 dar performanţe
superioare; acestea se referă în primul rând la integrarea în Internet şi
controlul aplicaţiilor deschise. Pentru instalare, este necesar cel puţin cu
procesor 80486 pe 66MHz cu 24MB RAM.
În anul 2000, firma Microsoft a lansat versiunea Windows 2000,
recomandată în primul rând pentru firme, şi prin care se încearcă combinarea
facilităţilor de integrare în Internet ale lui Windows ’98 cu securitatea lui
Windows NT, uşurinţa de utilizare a sistemului Windows 98 cu
caracteristicile de administrare, fiabilitate şi stabilitate ale lui Windows NT.
Pentru versiunile de tip server, care asigură o administrare eficientă a reţelei,
necesarul de memorie internă este mai mare decât pentru Windows 2000
Professional: minimum 128MB şi recomandat - 256MB. Problemele iniţiale
de compatibilitate a driverelor cu celelalte versiuni Windows au fost
rezolvate prin crearea unor drivere specifice. Facilităţile de acces la Internet
sunt integrate într-un pachet complet şi performant. Dedicarea versiunii
Windows 2000 Professional în special pentru afaceri este susţinută de faptul
că se tinde către reducerea costului total al utilizării sistemului, în condiţiile
asigurării unei productivităţi şi flexibilităţi ridicate.
Windows Millennium Edition (Windows Me) continuă linia de produse
Windows ’95, ’98, punând la dispoziţia utilizatorilor o serie de instrumente
noi pentru prelucrarea datelor multimedia: înregistrarea şi editarea
videofilmelor digitale, stocarea şi organizarea imaginilor, precum şi o bună
calitate a sunetului.
Trebuie de asemenea remarcate facilităţile Windows ME pentru
construirea unei mini-reţele locale de calculatoare: partajarea unei conexiuni
la Internet între mai multe calculatoare, partajarea imprimantelor, a fişierelor
de sunet şi a imaginilor. Windows Me este primul sistem de operare care
suportă standardul UPnP (Universal Plug and Play), ceea ce permite
conectarea şi deconectarea perifericelor fără a fi necesară repornirea
calculatorului, precum şi detectarea rapidă a resurselor care pot fi partajate
într-o reţea. Spre deosebire de Windows 2000, Millennium Edition este
dedicat utilizatorilor individuali (home users).
O comparaţie între sistemele Windows se poate face urmărind tabelul de
mai jos.
167
Versiunea Windows Win Win Win Win Win Win Win
3.1 3.11 NT ’95 ’98 ME 2000
Caracteristica
Integrarea în reţea Nu Da Da Da Da Da Da
Arhitectură pe 32 de biţi Nu Nu Da Da Da Da Da
Portabilitate Nu Nu Da Da Da Da Da
168
a unor programe sau redeschiderea rapidă a documentelor recent utilizate. Pe
bara de task-uri va apărea câte un buton pentru fiecare aplicaţie activă (de aici,
ele pot fi alese în regim de multitasking sau, echivalent, se poate folosi
combinaţia de taste Alt-Tab preluată din Windows 3.x). Opţiunile lui Start
sunt: Programs, pentru lansarea în execuţie a aplicaţiilor (această opţiune îl
înlocuieste pe Program Manager din Windows 3.x), Documents, pentru
accesarea rapidă a ultimelor documente prin deschiderea lor în editoarele
corespunzătoare, Settings, cu aplicaţii pentru setarea unor opţiuni ale
sistemului (aplicaţia Control Panel, folder-ul Printers, modificarea barei de
task-uri şi a meniului Start), Find, pentru căutarea de fişiere / foldere folosind
criterii complexe, Help, pentru lansarea în execuţie a aplicaţiei Help, Run,
pentru lansarea în execuţie a unei aplicaţii (dacă se dă o comandă) sau
deschiderea unui folder sau director (dacă acesta se specifică) într-o fereastră
numită fereastră de navigare (a se vedea mai jos tipurile de ferestre) şi Shut
Down, pentru oprirea lui Windows ’9x.
Vizualizarea elementelor calculatorului (drive-uri locale şi de reţea,
imprimante etc.) se poate realiza cu ajutorul icon-ului My Computer care,
activat, afişează elementele sub formă de icon-uri într-o fereastră. Pentru
navigarea în reţea se poate folosi Network Neighborhood iar pentru
recuperarea fişierelor şterse - Recycle Bin. Revenirea asupra unei operaţii se
poate realiza cu: opţiunea Edit - Undo, butonul Undo sau eventual opţiunea
corespunzătoare dintr-un meniu contextual.
Windows ’95 introduce notiunea de folder, care desemnează o grupare de
elemente diferite (fişiere, documente, aplicaţii sau foldere) sau, în termeni de
Windows 3.x, un grup de aplicaţii sau un director. Icon-urile pot reprezenta
foldere, fişiere sau programe, folosind pictograme specifice. Copierea şi
mutarea icon-urilor se poate realiza cu ajutorul mouse-ului ca în versiunile
Windows anterioare; aici însă, ele pot reprezenta fişiere sau foldere. Se preia,
din anterioarele versiuni Windows, stilul de operare (copiere / mutare) prin
zona de memorie Clipboard, care permite transferul unor obiecte de tipuri
diverse (fişiere, foldere, blocuri de text, imagini etc.).
În Windows ’9x se utilizează următoarele tipuri de ferestre: de navigare
(cu meniul File, Edit, View, Help - de exemplu My Computer), de explorare
(cu meniul File, Edit, View, Tools, Help - de exemplu Windows Explorer),
de aplicaţie (dacă conţin o aplicaţie deschisă), de document (într-o aplicaţie
care prelucrează documentul) sau de dialog, cu obiecte de control specifice.
Operaţiile cu ferestre sunt analoage celor din Windows 3.1x iar designul lor
este similar, cu mici modificări legate de simbolurile meniului sistem,
maximizării, minimizării (introducerea aplicaţiei în bara de task-uri) şi
închiderii ferestrelor.
169
Un mecanism foarte puternic, preluat din aplicaţiile Windows 3.1 (Word, Excel etc.),
este cel al meniurilor contextuale. Acestea sunt ataşate fiecărui obiect (icon, folder, meniu,
bara de task-uri, desktop), fiind accesibile cu butonul din dreapta al mouse-ului şi permit
realizarea unor operaţii complexe asupra elementului respectiv: copiere, mutare, ştergere,
redenumire, schimbarea caracteristicilor / proprietăţilor, crearea de obiecte noi. De
exemplu, folosind acest mecanism în Windows Explorer (succesorul lui File Manager) se
pot crea foldere (directoare) în poziţia dorită. Un alt exemplu ar fi aranjarea icon-urilor
(Arrange Icons) din meniul contextual al desktop-ului.
Shortcut-urile sunt un instrument puternic, introdus în Windows ’95 pentru
creşterea eficienţei în accesarea unor aplicaţii; ele sunt reprezentate prin icon-uri
speciale (cu o săgeată mică în coltul stânga jos). Se pot crea shortcut-uri la orice
obiect (fişier, program, folder, drive) şi se pot plasa oriunde (pe suprafaţa de
lucru, într-un folder sau într-o aplicaţie). Un dublu click pe icon-ul de shortcut are
acelaşi efect ca şi pe icon-ul corespunzător lui. Un shortcut se poate crea din
meniul File - Create Shortcut al ferestrei de navigare în care se găseşte obiectul,
din meniul contextual al obiectului (Create Shortcut) sau cu ajutorul mouse-ului
(cu tastele Ctrl-Shift apăsate sau cu opţiunea Create Shortcut(s) Here din meniul
care apare după deplasarea cu mouse-ul). Ştergerea unui shortcut (cu Delete sau
folosind icon-ul Recycle Bin) nu afectează obiectul căruia îi corespunde.
Menţionăm că shortcut-urile în folderul de programe sunt similare icon-urilor de
programe din grupurile lui Program Manager.
Utilizarea lui Windows Explorer este analoagă cu cea a lui File Manager din
Windows 3.1; în plus, meniurile contextuale permit realizarea mai uşoară a
multor operaţii (un click dublu pe un element este asociat opţiunii implicite din
meniul contextual). Marcarea elementelor se face analog cu cea din Windows 3.x
iar pentru operaţii de copiere sau mutare se pot folosi opţiunile Copy, Cut, Paste
din meniul Edit sau butoanele analoage (apariţia acestora poate fi activată /
dezactivată din View). Conţinutul unui folder se poate afişa (View) sub forma de
icon-uri sau ca listă de elemente, cu nume sau cu informaţii complete.
Pentru un nivel mai avansat de utilizare a lui Windows ’9x, se poate schimba
configuraţia meniului Start prin adăugare de submeniuri. În acest scop, se poate
folosi din meniul contextual al lui Start opţiunea Open iar apoi, din fereastra de
navigare deschisă, File - New - Folder sau Shortcut, în funcţie de necesităţi. O
altă posibilitate este de a folosi opţiunea Start - Settings - Taskbar (se pot adăuga
elemente noi cu Add sau se pot elimina elemente cu Remove).
Prezentare
170
UNIX a apărut în perioada anilor ‘70 (primul proiect MULTIX -
laboratoarele Bell ale societăţii AT&T) şi s-a dezvoltat la început în limbajul
B, înlocuit din 1973 de limbajul C.
Unix este un sistem multiutilizator şi multiacces care funcţionează pe
un sistem în timp partajat.
La început au fost dezvoltate două versiuni ale sistemului UNIX:
AT&T System III şi System V (1983);
Universitatea Berkley BSD 4.1, 4.2 şi 4.3.
Sistemele utilizate la ora actuală au preluat funcţionalităţi specifice din cele
două versiuni. Versiunea SunOS 4.1.3 (Solaris 1), de exemplu, care are originea
derivată din BDS 4.2, a introdus funcţionalităţi proprii: NFS Network File
System şi NIS Network Information Services, apoi a integrat funcţionalităţi
specifice versiunii System V: mesaje, semafoare, memorie partajată.
Versiunea 4.1 a adus nou standardizarea comenzilor, încărcare dinamică
a modulelor nucleului ca şi un nou tip de sistem de fişiere care permite
crearea fişierelor temporare în memoria virtuală.
Versiunea SunOS 5.0 (Solaris 2) este derivată din System V R4
(dezvoltat în colaborare de către Sun şi AT&T).
Evoluţia sistemului UNIX ar trebui să conducă până în anul 2000 la
un sistem portabil pe toate tipurile de sisteme de calcul.
Funcţiunile deja normalizate reprezintă 95% din totalul comenzilor
UNIX şi sunt conţinute în standardul XPG.
171
Comenzile sistemului de fişiere
Vom prezenta pe scurt funcţionarea următoarelor comenzi:
% mkdir: crearea unui director;
% rmdir: ştergerea unui director;
% cd: schimbarea directorului curent;
% pwd: afişarea numelui directorului curent;
% ls: listarea fişierelor dintr-un director;
% cp: copierea fişierelor;
% mv: schimbarea numelui unui fişier şi/sau deplasarea în arbore;
% ln: crearea unui inod pe un fişier;
% rm: ştergerea unui fişier;
% chmod: schimbarea drepturilor de acces la un fişier;
% chown: schimbarea proprietarului unui fişier;
% unmask: afişarea sau definirea măştii de creare a fişierelor;
% newgrp: schimbarea grupului.
Structura fişierelor sub UNIX este arborescentă compusă din directoare
şi fişiere. O submulţime a acestei structuri poate fi reprezentată astfel:
/
Fişiere
Fiecărui utilizator îi este asociat un număr numit user-id (uid). Acest uid
va fi utilizat pentru a evidenţia dreptul de proprietate asupra fişierului.
172
De asemenea, fiecare utilizator aparţine unui grup reperat printr-un
număr numit group-id (gid).
Astfel, pentru fiecare fişier există trei drepturi de acces (rwx):
r: dreptul de citire a fişierului;
w: dreptul de scriere şi modificare a fişierului;
x: dreptul de execuţie a fişierului.
Aceste drepturi sunt aplicabile pentru trei clase de utilizatori:
proprietarul fişierului (owner);
utilizatorii membrii ai aceluiaşi grup ca şi proprietarul (group);
toţi ceilalţi utilizatori ai sistemului (others).
owner group others
rwx rwx rwx
O bună protecţie pentru un fişier nepartajabil se poate realiza prin atribuirea
drepturilor: - r w - - - - - -, unde „-” specifică absenţa dreptului respectiv.
Directoare
Pentru un director, cheile rwx îşi schimbă semnificaţia faţă de cazul
fişierelor:
r: dreptul de citire şi deci de listare (ls) al directorului;
w: dreptul de scriere în director şi deci de ştergere a fişierelor pe
care le conţine;
x: dreptul de parcurgere a directorului (cd) interzice orice operaţie
asupra directorului, cea mai bună metodă de a-l proteja faţă de alţi
utilizatori.
Comanda unmask 066 poziţionează masca de creare a fişierelor cu
valoarea octală 066 şi are ca efect crearea directoarelor cu drepturile:
r w x - - x - - x şi fişierele cu drepturile: r w - - - - - - -.
Comenzi de bază
Majoritatea comenzilor UNIX deschid 3 fişiere (unităţi logice) care sunt
asignate astfel:
0: intrarea standard (stdin) este asociată tastaturii terminalului;
1: ieşirea standard (stdout) este asociată ecranului terminalului
2: ieşirea erorilor (stderr) este asociată ecranului terminalului.
O comandă care utilizează aceste dispozitive standard este numită filtru,
conform figurii următoare:
Stdin 0 Stdout 1
Comandă UNIX
173
Stderr 2
Este de asemenea posibilă redirectarea intrării şi ieşirii comenzilor către
un fişier sau către o altă comandă, prin utilizarea caracterelor >, >>, <, <<, I,
„ “.
Redirectarea ieşirii standard se realizează astfel:
% comandă > nume_fişier sau
% comandă >> nume_fişier.
În primul caz se crează fişierul sau se şterge dacă exista deja, iar în al
doilea caz se adaugă la sfârşitul fişierului specificat.
Redirectarea erorilor se face cu 2> sau 2>> în loc de > sau >>.
Redirectarea intrării standard se realizează sub forma următoare:
% comandă < nume_fişier
Redirectarea unei comenzi este numită pipe, este simbolizată prin
caracterul I sau ^, şi este reprezentată ca în figura următoare:
Stdin Stdout
Comanda Comanda Comanda
0 Unix 1 0 Unix 10 Unix 1
2 2 2
174
% cd nume_director
Comanda pwd (print working directory) permite afişarea numelui
directorului curent potrivit sintaxei următoare:
% pwd
Exemplu:
rwx - -x - - x simboluri de drepturi;
111 001 0 0 1 drepturi în binar: 711 în octal;
000 110 1 1 0 mască în binar; 066 în octal;
% unmask 066 poziţionare mască;
% unmask afişare mască
066
175
Exemplul 2: se doreşte trecerea directorului reper şi a tuturor fişierelor
sale în proprietatea utilizatorului paul:
% chown - R paul reper
Ştergerea fişierelor: rm
176
Comanda rm (remove) permite ştergerea fişierelor potrivit sintaxei:
% rm - irf fişier1 fişier2 . . . fişiern
Opţiunile din comandă au următoarea semnificaţie:
-i: mod de lucru interactiv (confirmare înaintea ştergerii);
-r: pentru un director se realizează ştergerea recursivă a tuturor
fişierelor sale ca şi a subdirectoarelor pe care le conţine;
-f: dacă fişierul este inexistent nu apare mesaj de eroare, iar dacă nu
există dreptul w, nu se cere confirmarea ştergerii.
177
Interpretoare de comenzi
Există trei interpretoare de comenzi: Bourne Shell, C-Shell şi Korn Shell.
De regulă sunt executate trei tipuri de comenzi:
a) comenzi interne care fac parte din shell (înainte de crearea procesului):
comenzi foarte frecvente: cd, pwd, umask, ...;
directive algoritmice: if, then, else, while, case, for, ...
b) comenzi externe conţinute în directoare (după crearea unui nou proces);
c) comenzi create prin funcţii shell.
Execuţia unei comenzi poate fi de mai multe feluri:
a) interactivă: comanda este lansată la terminal şi controlul este
returnat sistemului la terminarea acesteia;
b) asincronă (background): pentru execuţia unei compilări sau a unei
comenzi al cărei rezultat poate întârzia. Comanda este lansată
urmată de caracterul &;
c) înregistrată: lansată cu at, permite declanşarea execuţiei unui fişier
de comenzi la o dată specificată;
d) batch: lansată cu comanda batch (System V), crează o coadă de
aşteptare , iar fişierul se lansează când ajunge în capul cozii;
e) ciclică: este lansată cu comanda crontab (System V).
Editorul de texte vi
Acest editor posedă două moduri de lucru:
a) modul comandă (MC);
b) modul inserare (MI).
În modul inserare, cele mai importante comenzi sunt i (insert) sau a
(append), iar ieşirea din modul inserare se realizează prin apăsarea
tastei<ESCAPE>.
Modul comandă posedă două tipuri de comenzi:
a) comenzi care rămân în MC după execuţie;
b) comenzi care părăsesc MC şi fac să se treacă în MI.
Poşta electronică
Comanda mail este utilizată pentru emisia şi recepţia curierului
electronic între utilizatori. Un mesaj poate fi transmis către unul sau mai
mulţi utilizatori.
Salvare şi arhivare
Datele utilizate într-o reţea pot fi salvate pe dischetă cu ajutorul comenzii bar.
178
Comanda rsh permite execuţia unei comenzi pe un sistem de calcul la
distanţă (în anumite condiţii).
Comenzile rcp şi ftp permit transferul fişierelor între un nod local şi un
nod la distanţă, acţiune care necesită existenţa unor fişiere speciale care
realizează conectarea şi transferul propriu-zis.
X - Windows
X-Windows este un sistem de interacţiune cu utilizatorul, orientat spre
ferestre, care poate fi operaţional pe o mare varietate de sisteme de calcul
care lucrează sub sisteme de operare diferite.
În esenţă, sistemul X-Windows reprezintă o interfaţă utilizator grafică
(GUI) prin intermediul căreia se realizează independenţa faţă de sistemul de
operare şi de echipamentul hardware.
Scopul sistemului X-Windows este acela de a furniza programelor de
aplicaţie un mediu de lucru independent de particularităţile staţiei de lucru, a
sistemului de operare, a reţelei în care este integrat etc.
9. APLICAŢII JAVA
import java.io.*;
/*
Fie N un număr natural dat.
Să se citească repetat şi să se valideze N;
Să se calculeze corespondentul binar, octal, hexazecimal al lui N;
Să se afişeze cifrele numerelor astfel obţinute.
**/
class Reprezentare
{
public static void main (String argv[])
{
while (true){
InputStreamReader stdin = new
InputStreamReader(System.in);
BufferedReader console = new BufferedReader(stdin);
int N;
int N_valid;
179
String s1,s2;
//N_valid = Integer.parseInt(argv[0]); //numarul este
dat ca argument in linia de comanda
N_valid = 203;
try
{
System.out.print("N = ");
s1 = console.readLine();
N = Integer.parseInt(s1);
if (N != N_valid)
System.out.println("Numar invalid: introduceti un alt numar");
else
{
System.out.println("Reprezentarea in binar a numarului "
+ N + " este " + binar(N));
System.out.println("Reprezentarea in octal a numarului "
+ N + " este " + octal(N));
System.out.println("Reprezentarea in hexazecimal a
numarului " + N + " este " + hexazecimal(N));
}
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu este un numar");
System.exit(1);
}
}
}
180
i = 0;
if(n<=0) return(0);
while (n>0){
temp[i] = n % 2;
n = n/2;
i++;
}
for(int j = i-1;j>=0;j--)
rez = rez * 10 + temp[j];
return rez;
}
public static long octal(int n)
{
int rez = 0;
int i;
int temp[];
temp = new int[100];
i = 0;
if(n<=0) return(0);
while (n>0){
temp[i] = n % 8;
n = n/8;
i++;
}
for(int j = i;j>=0;j--)
rez = rez * 10 + temp[j];
return rez;
}
public static String hexazecimal(int n)
{
int rez = 0;
int i;
int temp[];
String s;
char aux;
s = "";
temp = new int[100];
i = 0;
if(n<=0) return Integer.toString(0);
181
while (n>0){
temp[i] = n % 16;
n = n/16;
i++;
}
for(int j = i-1;j>=0;j--)
if (temp[j] < 10)
s = s + temp[j];
else {
temp[j] = 'A' + (temp[j] - 10);
aux = (char)temp[j];
s = s + aux ;
}
return s;
}
}
import java.io.*;
/*
Fie m numărul de cifre pentru a = (am, am-1, .., a0) în reprezentare internă
(în sistemul binar).
Să se citească şi să se valideze m şi a;
Să se stabilească reprezentările externe posibile ale lui a;
Să se afişeze aceste reprezentări.
*/
class ExDoi
{
public static void main (String argv[])
{
while (true){
InputStreamReader stdin = new
InputStreamReader(System.in);
BufferedReader console = new BufferedReader(stdin);
int a, m;
182
String s1, s2;
try
{
System.out.print("m = ");
s1 = console.readLine();
m = Integer.parseInt(s1);
if (m <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
System.out.print("a = ");
s2 = console.readLine();
a = Integer.parseInt(s2);
if (a <= 0)
{
System.out.println("Numar binar invalid");
System.exit(1);
}
if (verificare(a,m,2) != 0)
{
System.out.println("Numar binar invalid");
System.exit(1);
}
System.out.println("Reprezentarea externa ca intreg a numarului
" + a + " este " + reprezentare_b(a,2));
System.out.println("Reprezentarea externa ca si caracter a numarului
" + a + " este " + (char)reprezentare_b(a,2));
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu este un numar");
System.exit(1);
183
}
}
}
184
}
}
import java.io.*;
class ExTrei
{
public static void main (String argv[])
{
while (true){
InputStreamReader stdin = new
InputStreamReader(System.in);
BufferedReader console = new BufferedReader(stdin);
int a, b, p, m, n;
String baza, s1, s2;
try
{
System.out.print("p = ");
baza = console.readLine();
p = Integer.parseInt(baza);
if (p <= 1 || p > 9)
185
{
System.out.println("Baza de numeratie invalida");
System.exit(1);
}
System.out.print("m = ");
s1 = console.readLine();
m = Integer.parseInt(s1);
if (m <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
System.out.print("a = ");
s2 = console.readLine();
a = Integer.parseInt(s2);
if (a < 0)
{
System.out.println("Numar invalid");
System.exit(1);
}
if (verificare(a, m, p) != 0)
{
System.out.println("Numar invalid in baza " + p);
System.exit(1);
}
System.out.print("n = ");
s1 = console.readLine();
n = Integer.parseInt(s1);
if (n <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
System.out.print("b = ");
s2 = console.readLine();
b = Integer.parseInt(s2);
if (b < 0)
{
System.out.println("Numar invalid");
186
System.exit(1);
}
if (verificare(b, n, p) != 0)
{
System.out.println("Numar invalid in baza " + p);
System.exit(1);
}
187
i++;
}
return 0;
}
public static long reprezentare_b(int n, int baza)
{
int rez = 0;
int i;
int temp[];
temp = new int[100];
i = 0;
if(n<=0) return 0;
while (n>0){
temp[i] = n % 10;
n = n/10;
i++;
}
for(int j = i-1;j>=0;j--)
rez = rez * baza + temp[j];
return rez;
}
public static long adunare(int a, int b, int m, int n, int p)
{
int rez = 0;
int i;
int temp[];
int carry;
temp = new int[100];
i = 0;
carry = 0;
if (n >= m){
while ((a>0) || carry !=0 ){
temp[i] = (a % 10 + b % 10 + carry) % p ;
carry = ((a % 10 + b % 10 + carry) / p);
a = a/10;
b = b/10;
i++;
}
for(int j = i-1;j>=0;j--)
rez = rez * 10 + temp[j];
188
}
else{
while ((b>0) || carry !=0 ){
temp[i] = (a % 10 + b % 10 + carry) % p ;
carry = ((a % 10 + b % 10 + carry) / p);
a = a/10;
b = b/10;
i++;
}
for(int j = i-1;j>=0;j--)
rez = rez * 10 + temp[j];
}
return rez;
}
}
import java.io.*;
class ExPatru
{
public static void main (String argv[])
{
while (true){
InputStreamReader stdin = new
InputStreamReader(System.in);
BufferedReader console = new BufferedReader(stdin);
int a, b, p, m, n;
String baza, s1, s2;
try
{
//mai intai citesc baza p
System.out.print("p = ");
189
baza = console.readLine();
p = Integer.parseInt(baza);
if (p <= 1 || p > 9)
{
System.out.println("Baza de numeratie invalida");
System.exit(1);
}
//apoi citesc numarul de cifre m al lui a
System.out.print("m = ");
s1 = console.readLine();
m = Integer.parseInt(s1);
if (m <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
System.out.print("a = ");
s2 = console.readLine();
a = Integer.parseInt(s2);
//apoi citesc numarul a
if (a < 0)
{
System.out.println("Numar invalid");
System.exit(1);
}
//verific corectitudinea numarului a in baza p
if (verificare(a, m, p) != 0)
{
System.out.println("Numar invalid in baza " +p);
System.exit(1);
}
//apoi citesc numarul de cifre n al lui b
System.out.print("n = ");
s1 = console.readLine();
n = Integer.parseInt(s1);
if (n <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
190
//apoi citesc numarul b
System.out.print("b = ");
s2 = console.readLine();
b = Integer.parseInt(s2);
if (b < 0)
{
System.out.println("Numar invalid");
System.exit(1);
}
//verific corectitudinea numarului a in baza p
if (verificare(b, n, p) != 0)
{
System.out.println("Numar invalid in baza " +p);
System.exit(1);
}
System.out.println("Scaderea celor doua numere
are ca rezultat " + scadere(a, b, m, n, p));
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu este un numar");
System.exit(1);
}
}
}
public static int verificare(int n, int m, int p)
{
int i;
if(n < 0)
return -1;
i = 0;
if(reprezentare_b(n,p) > (int)(Math.pow((double) p,
(double) m) - 1))
{
return -1;
191
}
while (n>0){
if ((n%10) >= p || (n%10) < 0)
return -1;
n = n/10;
i++;
}
return 0;
}
public static long reprezentare_b(int n, int baza)
{
int rez = 0;
int i;
int temp[];
temp = new int[100];
i = 0;
if(n<=0) return 0;
while (n>0){
temp[i] = n % 10;
n = n/10;
i++;
}
for(int j = i-1;j>=0;j--)
rez = rez * baza + temp[j];
return rez;
}
public static long scadere(int a, int b, int m, int n, int p)
{
int rez = 0;
int i;
int temp[];
int scad;
temp = new int[100];
i = 0;
scad = 0;
if ((a > b)){
while ((b>0)){
if (a % 10 < b %10){
temp[i] = (a % 10 + p - b % 10);
scad = 1;
192
}
else {
scad = 0;
temp[i] = (a % 10 - b % 10);
}
a = a/10 - scad;
b = b/10;
i++;
}
while (a > 0){
temp[i] = a % 10;
a = a/10 - scad;
scad = 0;
i++;
}
for(int j = i-1;j>=0;j--)
rez = rez * 10 + temp[j];
}
else
return -1;
return rez;
}
}
import java.io.*;
/*
Fie p baza unui sistem de numeraţie şi m numărul de cifre pentru
a = (am, am-1, …, a0) şi b = (bn, bn-1, ..., b0), scrise în baza p.
Să se citească şi să se valideze m, n, p, a şi b;
Să se calculeze produsul a × b în baza p;
Să se afişeze acest produs.
*/
class ExCinci
{
public static void main (String argv[])
193
{
while (true){
}
//apoi citesc numarul de cifre m al lui a
System.out.print("m = ");
s1 = console.readLine();
m = Integer.parseInt(s1);
if (m <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
//apoi citesc numarul a
for (i = m-1; i >= 0; i--){
System.out.print("a[" + i + "] = ");
194
// citesc numarul a[i], a i-a cifra a numarului a
s2 = console.readLine();
a[i] = Integer.parseInt(s2);
}
195
c[i] = 0;
for (i = 0; i < n; i++){
if (b[i] != 0){
mult = 0;
addt = 0;
}
for (j = 0; j < m; j++){
w =a[j] * b[i] + mult;
mult = w / p;
w = w % p;
w = c[i+j] + w + addt;
addt = w / p;
c[i+j] = w % p;
}
c[i+m+1] = mult + addt;
}
while ((k<0) && (c[k] == 0))
k ++;
System.out.println("Produsul celor doua numere are ca rezultat: ");
for (i = k; i >= 0; i--)
System.out.print(c[i]);
System.out.println(" ");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu este numar");
System.exit(1);
}
}
}
}
196
9.6 Conversia în zecimal a unui număr reprezentat în baza p
import java.io.*;
/*
Fie p baza unui sistem de numeraţie şi m numărul de cifre pentru a = (a m,
am-1, …, a0) scris în baza p.
Să se citească şi să se valideze m, p şi a;
Să se convertească în sistemul zecimal;
Să se afiseze numărul obtinut.
*/
class ExSase
{
197
char []S = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
}
public static int v(char k){
int rez = 0;
switch (k) {
case '0': rez = 0; break;
case '1': rez = 1; break;
case '2': rez = 2; break;
case '3': rez = 3; break;
case '4': rez = 4; break;
case '5': rez = 5; break;
case '6': rez = 6; break;
case '7': rez = 7; break;
case '8': rez = 8; break;
198
case '9': rez = 9; break;
case 'A': rez = 10; break;
case 'B': rez = 11; break;
case 'C': rez = 12; break;
case 'D': rez = 13; break;
case 'E': rez = 14; break;
case 'F': rez = 15; break;
default: System.out.println("Not a character"); rez = -1;
break;
}
return rez;
int a[];
int p, m, n, i, k, suma = 0, pr, j;
String baza, s1= "", s2 = "", w1;
a = new int [100];
while (true){
199
}
//apoi citesc numarul de cifre m al lui a
System.out.print("Numarul de cifre m = ");
s1 = console.readLine();
m = Integer.parseInt(s1);
if (m <= 0)
{
System.out.println("Numar de cifre invalid");
System.exit(1);
}
//apoi citesc numarul a
for (i = m-1; i >= 0; i--){
System.out.print("a[" + i + "] = ");
// citesc numarul a[i], a i-a cifra a numarului a
s2 = console.readLine();
a[i] = v(s2.charAt(0));
}
}
}
suma = 0;
pr = 1;
for (i = 0; i < m; i++){
suma = suma + pr * a[i];
pr = pr*p;
}
System.out.println("Numarul are ca rezultat in baza 10: ");
System.out.print(suma);
System.out.println(" ");
}
catch(IOException ioex)
200
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\"
nu este un numar");
System.exit(1);
}
}
}
}
import java.io.*;
/*
Fie N un număr în sistemul zecimal şi p 10 baza unui sistem de
numeratie.
– Să se citească şi să se valideze N şi p;
– Să se convertească N în baza p;
– Să se afiseze lista cifrelor acestui număr.
*/
201
class sapte
{
char []S = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
202
case '6': rez = 6; break;
case '7': rez = 7; break;
case '8': rez = 8; break;
case '9': rez = 9; break;
case 'A': rez = 10; break;
case 'B': rez = 11; break;
case 'C': rez = 12; break;
case 'D': rez = 13; break;
case 'E': rez = 14; break;
case 'F': rez = 15; break;
default: System.out.println("Not a character"); rez = -1;
break;
}
return rez;
}
public static void baza2(int p, float nr){
int s [], i,k;
s = new int [100];
k = 0;
while (nr != 0){
203
k++;
s[k] = (int)(p*nr);
nr = (p*nr) - s[k];
}
if (k>=1)
System.out.println(",");
for (i=1; i<k; i++)
System.out.print(""+ vi(s[i]));
System.out.println(" ");
}
public static void main (String argv[])
{
int a[];
int p, m, n, i, k, suma = 0, pr, j;
float nr;
String baza, s1= "", s2 = "", w1;
a = new int [100];
while (true){
}
//apoi citesc baza p
System.out.print("p = ");
baza = console.readLine();
p = Integer.parseInt(baza);
if (p < 2 || p > 16)
204
{
System.out.println("Baza de numeratie invalida");
System.exit(1);
}
n = (int)nr;
nr = nr - n;
baza1(p,n);
baza2(p,nr);
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\"
nu este un numar");
System.exit(1);
}
}
}
}
import java.io.*;
/*
Fie N un număr natural impar dat.
Să se citească repetat şi să se valideze N;
Să se construiască un careu magic de ordinul N;
Să se afiseze acest careu evidenţiind şi constanta magică.
205
*/
class opt
{
public static void main (String argv[])
{
int a[][];
int n, m1, m2, i, j, k;
float nr;
String baza, s1= "", s2 = "", w1;
a = new int [20][20];
206
i = m1;
j = m2;
}
else{
i = i+2;
if (i>n) i = i-n;
}
}
System.out.println("Careul magic este:");
for (i = 1; i < n; i++){
for (j = 1; j < n; j++)
System.out.print(a[i][j]+ " ");
System.out.println("");
}
System.out.println("");
System.out.println("Suma magica = "+ (n*(n*n+1) / 2) + " ");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu
este un numar");
System.exit(1);
}
}
}
import java.io.*;
/*
Fie R un număr scris cu cifre romane.
Să se citească şi să se valideze R;
Să se calculeze corespondentul lui R în scriere cu cifre zecimale;
Să se afişeze acest număr.
207
*/
class noua
{
public static void main (String argv[])
{
char cifra;
int i, n = 0;
boolean corect;
String s1;
int val_prec = 0, val_urm = 0;
InputStreamReader stdin = new
InputStreamReader(System.in);
BufferedReader console = new BufferedReader(stdin);
try
{
System.out.println("Numarul din cifre romane:");
s1 = console.readLine();
corect = true;
switch (s1.charAt(0)){
case 'M': val_prec = 1000; break;
case 'D': val_prec = 500; break;
case 'C': val_prec = 100; break;
case 'L': val_prec = 50; break;
case 'X': val_prec = 10; break;
case 'V': val_prec = 5; break;
case 'I': val_prec = 1; break;
default: corect = false; break;
}
if (corect == false){
System.out.println("Numar in cifre romane incorect!");
System.exit(0);
}
i = 1;
while ((corect == true) && (i < s1.length())){
switch (s1.charAt(i)){
case 'M': val_urm = 1000; break;
case 'D': val_urm = 500; break;
case 'C': val_urm = 100; break;
case 'L': val_urm = 50; break;
case 'X': val_urm = 10; break;
208
case 'V': val_urm = 5; break;
case 'I': val_urm = 1; break;
default: corect = false; break;
}
if (val_prec < val_urm){
n = n - val_prec;
}
else
n = n + val_prec;
val_prec = val_urm;
i++;
}
if (corect == true)
System.out.println("Numarul in scriere araba:" +
(n+val_prec));
else
System.out.println("Eroare: " + s1.charAt(i)+ " nu
este cifra romana");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu
este un numar");
System.exit(1);
}
}
}
import java.io.*;
/*
Fie N un număr natural dat.
Să se citească repetat şi să se valideze N;
209
Să se exprime în sistemul roman toate puterile lui 2 de la 1 până la N;
Să se afiseze aceste numere.
*/
class zece
{
public static void main (String argv[])
{
int x,y;
y = 1;
System.out.print("Program pentru exprimare a puterilor lui 2
in cifre romane:");
while (y <= 5000){
x = y;
System.out.print(y + " : ");
while (x > 1000){
System.out.print("M");
x = x - 1000;
}
if (x >= 900){
System.out.print("CM");
x = x-900;
}
if (x >= 500){
System.out.print("D");
x = x-500;
}
if (x >= 400){
System.out.print("CD");
x = x-400;
}
while (x >= 100){
System.out.print("C");
x = x - 100;
}
if (x >= 90){
System.out.print("XC");
x = x-90;
}
210
if (x >= 50){
System.out.print("L");
x = x-50;
}
if (x >= 40){
System.out.print("XL");
x = x-40;
}
while (x >= 10){
System.out.print("X");
x = x - 10;
}
if (x >= 9){
System.out.print("IX");
x = x-9;
}
if (x >= 5){
System.out.print("V");
x = x-5;
}
if (x >= 4){
System.out.print("IV");
x = x-4;
}
while (x >= 1){
System.out.print("I");
x = x - 1;
}
y = 2*y;
System.out.println(" ");
}
}
}
import java.io.*;
/*
Fie N un număr zecimal de trei cifre.
211
Să se citească repetat şi să se valideze N;
Să se dacă N este egal cu suma cuburilor cifrelor sale
Să se afiseze toate numerele cu proprietatea dată.
*/
class unusprezece
{
public static void main (String argv[])
{
int n, n1, a, b, c;
boolean ok;
char answer;
System.out.println ("Numerele de 3 cifre egale cu suma
cuburilor cifrelor sunt:");
System.out.println(" ");
}
}
import java.io.*;
/*
212
Fie p si q două baze de numeratie şi m numărul de cifre pentru a =
(am, am-1, …, a0) (pur fracţionar) scris în baza p.
Să se citească şi să se valideze m, p, q şi a;
Să se realizeze conversia lui a din baza p în baza q;
Să se afişeze lista cifrelor numărului obţinut.
*/
class doisprezece
{
static char []S = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
213
int rez = 0;
switch (k) {
case '0': rez = 0; break;
case '1': rez = 1; break;
case '2': rez = 2; break;
case '3': rez = 3; break;
case '4': rez = 4; break;
case '5': rez = 5; break;
case '6': rez = 6; break;
case '7': rez = 7; break;
case '8': rez = 8; break;
case '9': rez = 9; break;
case 'A': rez = 10; break;
case 'B': rez = 11; break;
case 'C': rez = 12; break;
case 'D': rez = 13; break;
case 'E': rez = 14; break;
case 'F': rez = 15; break;
default: System.out.println("Not a character"); rez = -1;
break;
}
return rez;
}
public static void baza1(int n, int q){
char s[];
214
int k;
int i = -1;
s = new char [16];
i = -1;
//trece din baza 10 in baza q pt partea intreaga
while (n != 0){
i = i + 1;
s[i] = (char)(n % q);
n = n / q;
}
for (k = i; k >= 0; k--)
System.out.print(vi(s[k]) + "");
System.out.println(" ");
}
while (true){
215
System.exit(1);
}
//apoi citesc baza p
System.out.print("p = ");
baza1 = console.readLine();
p = Integer.parseInt(baza1);
if (p < 2 || p > 16)
{
System.out.println("Baza de numeratie " + baza1
+ " este invalida");
System.exit(1);
}
//apoi citesc baza q
System.out.print("q = ");
baza2 = console.readLine();
q = Integer.parseInt(baza2);
if (q < 2 || q > 16)
{
System.out.println("Baza de numeratie " + baza2
+ " este invalida");
System.exit(1);
}
//apoi citesc numarul a
for (i = m-1; i >= 0; i--){
System.out.print("a[" + i + "] = ");
// citesc numarul a[i], a i-a cifra a numarului a
s2 = console.readLine();
a[i] = s2.charAt(0);
}
216
break;
}
}
if (valid == false ){
System.out.println("Numar invalid");
System.exit(1);
}
}
n = baza3(p,a,m);
baza1(n,q);
System.out.println(" ");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\"
nu este un numar");
System.exit(1);
}
}
}
}
217
import java.io.*;
/*
Fie n numărul de cifre binare pentru a = (a1, a2, …, an) care urmează să
fie trimis cu o paritate dată, p.
Să se citească şi să se valideze n, p şi a;
Să se stabilească dacă informaţia a fost transmisă corect;
*/
class treisprezece
{
public static void main (String argv[])
{
int n, i, p, nr;
boolean ok;
char a[];
a = new char [16];
String t, s1 = "", s2 = "";
System.out.println("Calculul paritatii unui şir de cifre:");
while (true){
218
p = Integer.parseInt(s1);
if ((p != 1) && (p != 0)){
System.out.println("Cifra incorecta");
System.exit(0);
}
//apoi citesc numarul a
for (i = n-1; i >= 0; i--){
System.out.print("a[" + i + "] = ");
// citesc numarul a[i], a i-a cifra a numarului a
s2 = console.readLine();
a[i] = s2.charAt(0);
if ((a[i] != '0') && (a[i] != '1')){
System.out.println("Cifra incorecta");
System.exit(0);
}
}
nr = 0;
for (i = 1; i < n; i++){
if (a[i] == '1')
nr ++;
}
if ((p+nr) % 2 == 0)
System.out.println("corect!");
else
System.out.println("incorect!");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\"
nu este un numar");
System.exit(1);
}
}
}
}
219
9.14 Codul lui Hamming pentru emisie mesaj
import java.io.*;
/*
Fie o transmisie care utilizează CH cu paritate impară pentru un mesaj
binar pe m biţi.
Să se citească şi să se valideze m şi mesajul de transmis;
Să se calculeze cei k biţi de control;
Să se afişeze mesajul transmis pe n = m + k biţi.
*/
class paisprezece
{
public static void main (String argv[])
{
int i, m, n, k, p, j, poz, l;
boolean ok;
char a[], b[];
a = new char [50];
b = new char [50];
String t, s1 = "", s2 = "";
System.out.println("Codul lui Hamming pentru emisie mesaj");
while (true){
221
if (s == 0)
System.out.println("Transm. Fara eroare");
else {
System.out.println("Eroare la bitul " + s);
if (b[s] == 1)
b[s] = 0;
else
b[s] = 1;
System.out.println("");
}
poz = p / 2;
m = n;
for (i = k; i>0; i--){
for (j = poz; j < m-1; j++)
b[j] = b[j+1];
m = m-1;
poz = poz / 2;
}
for (i = m; i > 0; i--)
System.out.println(b[i]);
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() +
"\" nu este un numar");
System.exit(1);
}
}
}
}
222
9.15 Codul lui Hamming pentru recepţie mesaj
import java.io.*;
/*
Fie o transmisie care utilizează CH cu paritate impară prin care s-a
receptionat un mesaj binar pe n biti.
Să se citească şi să se valideze n şi mesajul receptionat;
Să se verifice cei k biti de control de paritate;
Să se afişeze mesajul iniţial pe m = n - k biţi, după corectarea
eventualelor erori.
*/
class cincisprezece
{
public static void main (String argv[])
{
int i, m, n, k, p, j, poz, s, l;
boolean ok;
char a[], b[];
a = new char [50];
b = new char [50];
String t, s1 = "", s2 = "";
System.out.println("Codul lui Hamming pentru receptie mesaj");
while (true){
224
poz = 1;
for (i = 0; i < k; i++){
if ((b[i] %2) == 0)
a[poz] = 1;
poz = poz * 2;
}
for (i = n-1; i >= 0; i--)
System.out.print(a[i]);
System.out.println("");
System.out.println("End.");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\"
nu este un numar");
System.exit(1);
}
}
}
}
225
9.16 Fişiere în Java
import java.io.*;
/*
Implementare fisier cu studentii din facultate împărtiti pe grupe: citire,
afisare, contorizare.
*/
class saisprezece
{
public static void main (String argv[])
{
String numefis;
String numeg;
FileOutputStream fout;
FileInputStream fin;
int n, i;
String t, s1 = "", s2 = "";
InputStreamReader stdin = new InputStreamReader(System.in);
BufferedReader console = new BufferedReader(stdin);
try
{
System.out.print("Dati numele fisierului: ");
numefis = console.readLine();
// Deschidere output stream
fout = new FileOutputStream (numefis);
fin.close();
}
// Pentru tratarea conditiilor de eroare
catch (IOException e)
{
System.err.println ("Unable to write to file");
System.exit(-1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\" nu este un
numar");
System.exit(1);
}
}
}
227
9.17 Eliminare spaţii excedentare şir de caractere
import java.io.*;
/*
Modelare text citit de la tastatură prin eliminarea spatiilor excedentare.
*/
class saptesprezece
{
public static int i, j;
public static char a[], b[];
public static void sf(){
i = 0;
while(i < j){
System.out.print(b[i]);
i = i+1;
}
System.out.print(" ");
}
229
//se citeste caracter cu caracte textul
s1 = console.readLine();
a[i] = s1.charAt(0);
i = i+1;
if (a[i-1] =='%'){
//caracter de final
a[i-1] = '}';
a[i] = '%';
i = -1;
System.out.println("Textul corectat este: ");
spinit();
System.out.println(" ");
System.out.println(" ");
break;
}
}
// Pentru tratarea conditiilor de eroare
catch (IOException e)
{
System.err.println ("Unable to write to file");
System.exit(-1);
}
}
}
}
230
9.18 Conversie din reprezentare externă în VMSP
import java.io.*;
/*
Fie numărul zecimal N o reprezentare externă a informatiei unui
sistem de calcul.
· Să se citească repetat si să se valideze N;
· Să se stabilească reprezentarea internă în VMSP a lui N;
· Să se afiseze în hexazecimal această valoare.
*/
class optsprezece
{
231
return rez + "";
}
public static int v(char k){
int rez = 0;
switch (k) {
case '0': rez = 0; break;
case '1': rez = 1; break;
case '2': rez = 2; break;
case '3': rez = 3; break;
case '4': rez = 4; break;
case '5': rez = 5; break;
case '6': rez = 6; break;
case '7': rez = 7; break;
case '8': rez = 8; break;
case '9': rez = 9; break;
case 'A': rez = 10; break;
case 'B': rez = 11; break;
case 'C': rez = 12; break;
case 'D': rez = 13; break;
case 'E': rez = 14; break;
case 'F': rez = 15; break;
default: System.out.println("Not a character"); rez = -1;
break;
}
return rez;
232
{
while (true){
233
else
b[0] = 1;
for (i = 1; i < 31; i++)
b[i] = 0;
l = 8;
while (ed > 0){
b[l] = (int)(ed % 2);
l = l-1;
ed = ed / 2;
}
for (i = 1; i < er; i++)
b[8+i] = ai[er-i];
for (i = 1; i < j; i++)
b[8+er+i] = ar[i];
System.out.println("Reprezentarea interna in VMSP a lui N este:");
for (i = 0; i < 31; i++)
System.out.print(b[i]+"");
System.out.println(" ");
System.out.println("Reprezentarea in hexazecimal este:");
234
}
import java.io.*;
/*
Fie numărul N în sistem octal o reprezentare internă în VMSP.
Să se citească repetat şi să se valideze N;
Să se stabilească reprezentarea externă a lui N;
Să se afiseze în zecimal această valoare.
*/
class nouasprezece
{
public static void main (String argv[])
{
int m;
boolean valid = true;
int p, s, c, i, k, er;
float n, x, sr, pr;
int a[], b[];
a = new int [100];
b = new int [100];
String baza, s1= "", s2 = "", w1;
while (true){
}
System.out.print("Introduceti a[0] un intreg intre 0
şi 3 ");
s1 = console.readLine();
a[0] = Integer.parseInt(s1);
if ((a[0] < 0) || (a[0] > 3)){
System.out.println("Numarul de cifre este invalid");
System.exit(1);
}
//apoi citesc numarul a
for (i = 1; i < m; i++){
System.out.print("a[" + i + "] = ");
// citesc numarul a[i], a i-a cifra a numarului a
s2 = console.readLine();
a[i] = s2.charAt(0);
}
valid = true;
for (i = 1; i < m; i++){
if ((a[i] < '0') || (a[i] > '7')){
valid = false;
break;
}
}
if (valid == false ){
System.out.println("Numar invalid");
System.exit(1);
}
for (i = 0; i < m; i++)
System.out.print("" + a[i]);
System.out.println("");
b[0] = a[0] / 2;
b[1] = a[0] % 2;
for (i = 1; i < m; i++){
c = a[i];
236
b[3*i+1] = c % 2;
c = c / 2;
b[3*i] = c / 2;
b[3*i-1] = c / 2;
}
k = 2+m*3;
for (i = k; i < 31; i++)
b[i] = 0;
for (i = 0; i < 31; i++)
System.out.print("" + b[i]);
System.out.println("");
if (b[0] == 1)
System.out.print("-");
else
System.out.print("+");
s = 0;
p = 1;
for (i = 8; i >= 1; i--){
s = s + b[i]*p;
p = p*2;
}
er = s-128;
sr = 0;
pr = 1/2;
for (i = 9; i < 31; i++){
sr = sr+b[i]*pr;
pr = pr/2;
}
System.out.print(sr+ "*" + " 2 la puterea " + er);
System.out.println(" ");
}
catch(IOException ioex)
{
System.out.println("Eroare la intrare");
System.exit(1);
}
catch(NumberFormatException nfex)
{
System.out.println("\"" + nfex.getMessage() + "\"
nu este un numar");
237
System.exit(1);
}
}
}
}
import java.io.*;
class ceaMaiLungaLinie
{
public static void main (String argv[])
{
String numefis;
String line = "";
FileInputStream fin;
int maxLength = 0;
String maxLine = "";
try
{
System.out.println("Dati numele fisierului: ");
numefis = console.readLine();
if(maxLength == 0)
System.out.println("Fisierul de intrare este gol. ");
else{
System.out.println("Cea mai lunga linie este");
System.out.println(maxLine);
System.out.println("si are");
System.out.println(maxLength + " caractere.");
}
}
catch(Exception e)
{
System.out.println("Eroare citire fisier");
System.exit(1);
}
}
}
239
BIBLIOGRAFIE SELECTIVĂ
240
[Null 03] L. Null, J. Lobur, The Essentials of Computer
Organization and Architecture, Jones and Bartlett
Publishers, 2003.
241