Sunteți pe pagina 1din 51

Cuprins

1. Introducere ............................................................................................................ 3

2. Caracteristici ale limbajelor de programare ................................................. 5

3. Definirea problemei ............................................................................................. 7

4. Alegerea structurilor şi tipurilor de date utilizate ..................................... 10

5. Construirea algoritmilor şi a schemelor logice .............................................. 11

6. Proiectarea structurii produsului software ................................................... 16

7. Textul sursă al programului ............................................................................... 18

8. Crearea documentaţiei aferente produsului program ................................. 28

9. Testare şi implementare ..................................................................................... 31

10. Analiză cantitativă şi calitativă ....................................................................... 35

11. Concluzii ................................................................................................................. 37

Anexa 1 ........................................................................................................................ 39

Anexa 2 ........................................................................................................................ 48

Anexa 3 ........................................................................................................................ 49

Bibliografie ................................................................................................................. 51
1. Introducere
Disciplina LIMBAJE DE ASAMBLARE are ca obiectiv
prezentarea limbajului de asamblare si modului de utilizare a acestuia în
diferite aplicaţii. Limbajul de asamblare permite înţelegerea la nivel de
amănunt a ceea ce se întâmpla în realitate într-un calculator.
Familiarizarea cu un asemenea limbaj este mai mult decât benenefică
pentru un programator, contribuind la eficienţa programelor dezvoltate
indiferent de limbajul utilizat.
Există mai multe motive pentru care programarea în limbaj de
asamblare este necesară. Codul executabil generat din programe scrise în
limbaje de asmblare – ASM – se execută în general foarte rapid. Unele
module de program trebuie implementate în ASM datorită acestei viteze
de lucru. Uneori, o parte a unui program este scrisă într-un limbaj de
nivel înalt, iar modulele critice sunt scrise ca proceduri ASM, apelate la
rândul lor de modulele de nivel înalt. Există situaţii în care este nevoie de
acces direct la dispozitivele de intrare/ieşire sau la locaţii fizice de
memorie, iar aceste operaţii nu pot fi executate în unele limbaje de nivel
înalt. De exemplu, la calculatoare personale, programele TSR şi rutinele
de tratare a întreruperilor sunt aproape totdeauna scrise în ASM. Pe scurt,
limbajul de asamblare oferă viteze de execuţie şi acces la hardware care
nu pot fi disponibile (cel mai adesea) în limbaje de nivel înalt.
Un alt aspect important este cel al dezvoltării de programe pentru
echipamente dedicate. Nu toate programele executabile sunt destinate
calculatoarelor de uz general. Dezvoltarea masivă a microprocesoarelor a
făcut ca acestea să controleze în prezent funcţionarea celor mai diverse
dispozitive tehnice, de la carduri bancare până la echipamente de control
industrial sau pentru comanda avioanelor.
De asemenea există şi un puternic rol formativ al programării în
limbaj de asamblare. Un programator nu ajunge niciodata la un nivel
superior, dacă nu trece prin dezvoltarea de programe ASM.
Programatorul care cunoaşte principiile de realizare a limbajelor de
asamblare va trece cu uşurinţă de la utilizarea corectă a unui limbaj la
altul, deşi aparţin unor generaţii diferite. Limbajul de asamblare defineşte
operaţii elementare, iar programatorul gestionează toate resursele
programului. Există posibilitatea de a construi secvenţe de instrucţiuni şi
de a urmări din aproape în aproape prelucrările şi rezultatele corecte sau
eronate. Pentru fiecare rezultat există posibilitatea de a descrie

3
mecanismul de realizare şi de a identifica adevăratele cauze care duc la
erori.
Pe parcursul pregătirii sunt predate cursuri şi se efectuează lucrări
practice, iar în final trebuie elaborat un proiect care condiţionează
intrarea în examen. Proiectul are ca obiectiv realizarea unei aplicaţii care
permite studentului din anul trei de la Specializarea Informatică
Economică, Facultatea de Cibernetică, Statistică şi Informatică
Economică să însuşească şi să utilizeze în mod eficient limbajul de
asamblare în soluţionarea problemei alese.
Pentru a elabora proiectul se parcurg următorii paşi:
• se defineşte problema de realizat;
• se construieşte modelul care stă la baza efectuării
calculelor;
• se identifică datele care sunt folosite pentru rezolvarea
problemei;
• se elaborează structura produsului software;
• se stabilesc proprietăţile pe care trebuie să le îndeplinească
datele;
• se elaborează schemele logice;
• se scriu module de program care se asamblează;
• se testează produsele software;
• se procedează la implementare.

Acest ghid furnizează atât elemente privind tehnologia de


elaborare a proiectului, cât şi modalităţi rezolvare a problemelor şi de
analiză a rezultatelor.
Ghidul se încheie cu o listă orientativă de proiecte propuse, care
se constituie într-un punct de plecare la definirea şi realizarea aplicaţiei,
individualizate la nivelul fiecărui student.
Autorii sunt recunoscători tuturor celor care prin sugestii şi
observaţii contribuie la îmbunătăţirea ediţiei viitoare a acestui ghid.

Autorii.

4
2. Caracteristici ale limbajelor de asamblare
În cadrul unui proiect la disciplina „Limbaje de Asamblare”
problema de soluţionat este aleasă de student. O problemă se deosebeşte
de alta prin nivelul de complexitate, nivel care se regăseşte prin
dimensiunea produsului software, exprimată ca număr de linii sursă. La
rezolvarea problemei trebuie să se ţină cont de caracteristicile limbajelor
de asamblare.
Limbajele de programare evoluate posedă implementare la nivel
de compilatoare, care realizează:
• alocări automate de memorie pentru operanzii utilizaţi, dar
nedefiniţi în program;
• iniţializări la definire a operanzilor;
• semnalarea neconcordanţelor între natura operanzilor sau
a incompatibilităţilor, cu efectuarea corecţiilor celor mai
probabile sau prin eliminarea de instrucţiuni din secvenţă;
• conversiile necesare pentru a asigura gradul de
omogenitate necesar al prelucrărilor.

Limbajele de asamblare presupun existenţa la dispoziţia


programatorului a tuturor
resurselor sistemului de calcul. Acest lucru înseamnă că programatorul
este obligat:
• să definească în program toţi operanzii;
• să iniţializeze toate zonele de memorie;
• să asigure omogenitatea operanzilor în vederea efectuării
corecte a operaţiilor de calcul.

În programele scrise în limbaj de asamblare se execută exact


operaţiile pentru care există instrucţiuni. Dacă un operand nu este definit
dar este utilizat, asamblorul semnalează acest eveniment ca fiind major şi
nu va proceda la trecerea la etapele ulterioare asamblării. Dacă un
operand nu a fost iniţializat, se va lucra cu conţinutul existent al zonei de
memorie. Simplitatea programului asamblor nu permite analiza
corelaţiilor dintre instrucţiuni în aşa fel încât să semnalizeze că se
folosesc variabile neiniţializate.
De asemenea în programele scrise în limbaj de asamblare se află
instrucţiuni dispuse una după alta, care formează secvenţe lineare.
Apariţiile instrucţiunilor de salt întrerup caracterul liniar al programelor.

5
Limbajele de programare sunt structurate în definiri de tipuri de operanzi
şi referiri de operanzi în vederea prelucrării. Contextul de prelucrare
începe cu definirea operanzilor. Între modul de definire şi modul de
utilizare există restricţii pe care programatorul trebuie să le respecte.
Orice program foloseşte operanzi şi operatori. Limbajul de asamblare
permite structurarea distinctă, pe segmente a datelor, stivei şi a codului
executabil. Mai mult, există posibilitatea de a defini o variabilă oriunde
în segmente şi de a o referi cu semnificaţia pe care contextul (cod
instrucţiune, poziţie în lista de operanzi) îl dă. În limbajele de asamblare
sunt definite modalităţi variate de referire a operanzilor (adresare directă,
indirectă, indexată, bazată etc.). Octeţi sunt puşi în corespondenţă cu
identificatorii şi cu etichete. Întrucât o instrucţiune efectuează o operaţie
simplă şi instrucţiunile se organizează în secvenţe, programul scris în
limbajul de asamblare este văzut ca secvenţe şi nu ca expresii. Mai mult,
limitele de poziţionare a instrucţiunilor în secvenţe reduc gradul de
compactare a programelor.

6
3. Definirea problemei
Se doreşte evidenţierea migrări populaţiei pentru un număr dat de
judeţe. Se doreşte calculul pentru fiecare judeţ în parte a unor indicatori
care să evidenţieze migraţia populaţiei. Numărul judeţelor este limitat la
5 iar numele judeţelor se preia dintr-un masiv sau fişier sau se citeşte de
la tastatură. Datele de ieşre se memorează într-un fişier text şi pentru
fiecare judeţ se afişează în valoare absolută numărul populaţiei care a
emigrat, imigrat şi sporul înregistrat – numărul populaţiei de la începutul
perioadei de calcul plus numărul imigranţilor minus numărul
emigranţilor. Se ia în considerare o singură perioada de calcul.
În primul rând se stabilesc ieşirile.
Acestea sunt:
• sub forma unui număr;
• sub forma unui şir de numere;
• sub forma unui tabel;
• sub forma mai multor tabele cu structuri diferite;
• sub formă de fişiere;
• sub formă grafică.

Precizând exemple de control ce conţin valori numerice se


procedează la clasificarea situaţiilor frecvent întâlnite şi la identificarea
excepţiilor.
Toate acestea trebuie să fie regăsite în tabele de date, întrucât la
testare programul foloseşte exclusiv datele din aceste tabele. Pentru a
vedea cum programul execută transformările necesare asupra datelor de
intrare se testează toate variantele care există în aceste tabele de date. Pe
baza datelor introduse se obţin conform algoritmului o serie de rezultate
care sunt confruntate apoi cu rezultatele produse de program.
În al doilea rând, se stabilesc date iniţiale, ceea ce se furnizează
ca intrări de către program. Se stabilesc modalităţi de obţinere
(măsurători, documente primare, alte surse ce furnizează date).
În al treilea rând, se stabilesc formulele de calcul, care sunt, de
regulă, sub forma:
n
S = ∑ xi ;
i
n
S = ∑ xi ⋅ p i ;
i

7
De asemenea , se impun condiţii pentru includerea elementelor în
formule:
n
S = ∑ xi
i
xi > 0
sau
n
S = ∑ xi
i
xi < 0
Este important să se stabilească:
• numărul de componente;
• variabilele, modul de regrupare.

Trebuie văzut dacă toate ieşirile (rezultatele) se obţin folosind


toate datele de intrare.
Există următoarele situaţii care se întâlnesc în definirea
problemei:

• Problemă bine definită. Rezultatele se obţin din date.

intrări: n, x1, x2, ..., xn


ieşiri: x
n

formulă: ∑x i
x= i =1

• Problemă subdefinită. Se doresc multe rezultate şi nu


sunt suficiente date de intrare.

intrări: n, x1, x2, ..., xn


ieşiri: x
n

formulă: ∑x i fi
x= i =1

n
lipsesc: f1,f2, ..., fn

8
• Problemă supradefinită. Se găsesc mai multe date de
intrare, şi nu sunt folosite.

n, x1, x2, ..., xn


intrări: f1,f2, ..., fn
y1,y2, ..., yn
ieşiri: x
n

formulă: ∑x i fi
x= i =1

n
se găsesc în plus: y1,y2, ..., yn

Situaţia în care problema este bine definită este ideală. În cazul în


care problema este subdefinită se adaugă date de intrare, iar în cazul în
care problema este supradefinită se pot şterge date de intrare sau adăuga
rezultate.

Pentru o înţelegere mai bună a problemei se consideră un caz


practic. Fie lista judeţelor memorate într-un tabel în modul următor:

Tabel 1. Exemplu de lista judeţelor utilizate în program.

Denumire Cod zecimal Cod hexazecimal


judeţ/Prescurtare
Ilfov (IF) 0 00
Constanţa (CT) 1 01
Galaţi (GL) 2 02
Cluj (CJ) 3 03
Timiş (TM) 4 04

În tabelul 2 sunt prezentate datele cu care se operează în calculul


indicatorilor care evidenţiază migraţia populaţiei.

9
4. Alegerea structurilor şi tipurilor de date utilizate
Se ţine cont că se operează cu date privind migraţia populaţiei şi
atunci majoritatea datelor de intrare şi ieşire se abstractizează în masive
uni şi bi-dimensionale precum şi a fişierelor binare şi text. Se efectuează
alegerea tipurilor de date utilizate în program. Este evident că deoarece
se lucrează cu număr de populaţie, matricele care memorează dinamica
populaţiei la o anumită perioada de timp vor avea elemente de tip întreg.
Mai mult se vor elabora programe pentru procesoare standard (Intel,
AMD) de PC-uri şi deci se vor folosi limbajele de asamblare puse la
dispoziţie de acestea, adică se vor folosi tipurile de date pe care acestea le
recunosc.
Pentru numere întregi alegerea tipului de date se face astfel:
• dacă numerele aparţin intervalului [-128, +127] sau [0,
255], se alege memorarea pe un octet (1 byte), folosindu-
se descriptorul db (define byte);
• dacă numerele aparţin intervalului [-32768, +32767] sau
[0, 65535], se alege memorarea pe doi octeţi (2 bytes – 1
cuvânt), folosindu-se descriptorul dw (define word);
• dacă numerele aparţin intervalului [-231-1, +231-1] sau [0,
232-1], se alege memorarea pe patru octeţi (4 bytes – 2
cuvinte), folosindu-se descriptorul dd (define double
[word]);
• dacă numerele aparţin intervalului [-263-1, +263-1] sau [0,
264-1], se alege memorarea pe opt octeţi (8 bytes – 4
cuvinte), folosindu-se descriptorul dq (define quad
[word]);

În mod normal, operaţiile se efectuează pe maximum 16 biţi.


Pentru lucru cu valori mai mari, se folosesc registrele extinse, pe
32 de biţi.
În acest caz pentru că valorile se referă la numărul populaţiei din
câteva judeţe – valori de maxim câteva zeci de milioane – se alege
folosirea tipului de date pe patru octeţi, folosind descriptorul dd şi se va
lucra cu registrele extinse ale microprocesorului.

10
5. Construirea algoritmilor şi a schemelor logice
Se memorează într-un vector de cinci elemente prescurtările
judeţelor. Fiecare element din vector are 2 octeţi pentru a memora
prescurtările. De exemplu pentru cinci judeţe: Ilfov, Constanţa, Galaţi,
Cluj, Timiş se memorează în vector (vectjud) astfel: vectjud[0] = IF,
vectjud[1] = CT, vectjud[2] = GL, vectjud[3] = CJ, vectjud[4] = TM.
Pentru o perioadă dată – perioadă fixă de un an – se memorează
într-o matrice date despre populaţia din cele 5 judeţe în modul următor –
se reconstruieşte Tabelul 2 dar valorile memorate sunt în hexazecimal pe
patru octeţi adică 8 cifre hexazecimale:

Tabel 3. Exemplu de date privind migraţia populaţiei – date reprezentare


hexazecimală.

Judeţ/ 00 01 02 03 04
Judeţ

00 (IF) 00 00 00 00 00
20 00 00 00 00
16 C3 03 07 06
E6 50 E8 D0 A4
01 (CT) 00 00 00 00 00
00 06 00 00 00
7D 41 0F 00 00
00 90 A0 32 64
02 (GL) 00 00 00 00 00
00 00 05 00 00
88 2E E1 00 00
B8 E0 2F 00 78
03 (CJ) 00 00 00 00 00
00 00 00 05 00
4E 06 1B 57 2A
20 A4 BC 5A F8
04 (TM) 00 00 00 00 00
00 00 00 00 05
52 00 00 00 8A
08 78 69 D2 70

11
Interpretarea tabelului 3 este identică cu intrepretarea tabelului 2.
Trebuie efectuate calculele anumitor indicatori pentru a evidenţia
migraţia populaţiei:
• Indicator 1: numărul maxim de emigranţi dintr-un anumit
judeţ, se calculează ca maximul elementelor de pe linia
matricei mai puţin elementul de pe diagonala principală;
IND1i = max (matrdate[i ][ j ]) , unde i ∈ {0,4} , i ≠ j şi i
j∈{0 , 4}

reprezintă judeţul pentru se calculează indicatorul iar


matrdate este matricea în care sunt memorate datele din
tabelul 3.
De exemplu pentru judeţul 04 (TM) IND14 =
max (matrdate[4][ j ]) = 21.000 = 00005208.
j∈{0 , 4}

• Indicator 2: numărul minim de emigranţi dintr-un anumit


judeţ, se calculează ca minimul elementelor de pe linia
matricei mai puţin elementul de pe diagonala principală;
IND2i = min (matrdate[i ][ j ]) , unde i ∈ {0,4} , i ≠ j şi i
j∈{0 , 4}

reprezintă judeţul pentru se calculează indicatorul iar


matrdate este matricea în care sunt memorate datele din
tabelul 3.
De exemplu pentru judeţul 04 (TM) IND24 =
min (matrdate[4][ j ]) = 105 = 00000069.
j∈{0 , 4}

• Indicator 3: numărul maxim de imigranţi într-un anumit


judeţ, se calculează ca maximul elementelor de pe coloana
matricei mai puţin elementul de pe diagonala principală;
IND3j = max (matrdate[i ][ j ]) , unde j ∈ {0,4} , i ≠ j şi j
i∈{0 , 4}

reprezintă judeţul pentru se calculează indicatorul iar


matrdate este matricea în care sunt memorate datele din
tabelul 3.
De exemplu pentru judeţul 04 (TM) IND34 =
max (matrdate[i ][4]) = 11.000 = 00002AF8.
i∈{0 , 4}

12
• Indicator 4: numărul minim de imigranţi într-un anumit
judeţ, se calculează ca minimul elementelor de pe coloana
matricei mai puţin elementul de pe diagonala principală;
IND4j = min (matrdate[i ][ j ]) , unde j ∈ {0,4} , i ≠ j şi j
i∈{0 , 4}

reprezintă judeţul pentru se calculează indicatorul iar


matrdate este matricea în care sunt memorate datele din
tabelul 3.
De exemplu pentru judeţul 04 (TM) IND44 =
min (matrdate[i ][4]) = 11.000 = 00002AF8.
i∈{0 , 4}

• Indicator 5: numărul total de emigranţi dintr-un anumit


judeţ, se calculează ca suma elementelor de pe linia
matricei mai puţin elementul de pe diagonala principală;
4
IND5i = ∑ (matrdate[i][ j ]) ,
j =0
unde i ∈ {0,4} , i ≠ j şi i

reprezintă judeţul pentru se calculează indicatorul iar


matrdate este matricea în care sunt memorate datele din
tabelul 3.
De exemplu pentru judeţul 04 (TM) IND54 =
3

∑ (matrdate[4][ j ]) = 21.435 = 000053BB.


j =0

• Indicator 6: numărul total de imigranţi într-un anumit


judeţ, se calculează ca suma elementelor de pe coloana
matricei mai puţin elementul de pe diagonala principală;
4
IND6j = ∑ (matrdate[i][ j ]) ,
i =0
unde i ∈ {0,4} , i ≠ j şi j

reprezintă judeţul pentru se calculează indicatorul iar


matrdate este matricea în care sunt memorate datele din
tabelul 3.
De exemplu pentru judeţul 04 (TM) IND64 =
4

∑ (matrdate[i][4]) = 12.920 = 00003278.


i =0

• Indicator 7: numărul populaţiei rămase la sfârşitul


perioadei statistice în respectivul judeţ, se calculeaza ca

13
elementul de pe diagonala principală corespunzător
judeţului pentru care se calculează indicatorul plus
Indicatorul 6 pentru judeţul respectiv minus Indicator 5
pentru acelaşi judeţ.
IND7i = matrdate[i][i] + IND6i – IND5i.
De exemplu pentru judeţul 04 adică i=4, IND74 =
matrdate[4][4] + (12920 – 21435) = 363120 – 8515 =
354605 = 0005692D.

Cei şapte indicatori de mai sus sunt indicatori ce se calculează


fiecărui judeţ în parte, următori patru indicatori sunt indicatori agregaţi şi
medii ce sunt corespunzători tuturor judeţelor.
Astfel se calculează:
• Indicator 8: maximul total al emigranţilor şi este maximul
dintre toţi cei 5 (câte judeţe sunt) indicatori Indicator 1;
IND8 = max( IND1i ) , unde i ∈ {0,4} .
i

• Indicator 9: minimul total al emigranţilor şi este minimul


dintre toţi cei 5 (câte judeţe sunt) indicatori Indicator 2.
IND9= min ( IND2 i ) , unde i ∈ {0,4} .
i

• Indicator 10: maximul total al imigranţilor şi este maximul


dintre toţi cei 5 (câte judeţe sunt) indicatori Indicator 3;
IND10 = max( IND3 i ) , unde i ∈ {0,4} .
i

• Indicator 11: minimul total al imigranţilor şi este minimul


dintre toţi cei 5 (câte judeţe sunt) indicatori Indicator 4.
IND11 = min ( IND4 i ) , unde i ∈ {0,4} .
i

• Indicator 12: numărul total de emigranţi din toate judeţele


şi este suma tuturor celor 5 indicatori Indicator 5;
IND12 = ∑ IND5 i , unde i ∈ {0,4} .
i

• Indicator 13: numărul total de imigranţi către toate


judeţele şi este suma tuturor celor 5 indicatori Indicator 6;
IND13 = ∑ IND6 i , unde i ∈ {0,4} .
i

• Indicator 14: numărul mediu de emigranţi din toate


judeţele şi este valoarea Indicatorului 12 împărţit la 5, câte
judeţe sunt luate în calcul;
IND14 = IND12/5;

14
• Indicator 15: numărul mediu de imigranţi către toate
judeţele şi este valoarea Indicatorului 13 împărţit la 5, câte
judeţe sunt luate în calcul.
IND15 = IND13/5;

Trebuie avut în vedere că pentru calculul indicatorului 14 şi 15 se


vor folosi variabile reale şi proceduri specifice de afişare variabilelor
reale. Problema modului de afişare şi preluare a numerelor reale este des
întâlnită în folosirea limbajelor de asamblare iar pentru rezolvarea ei în
capitolul următor se vor elabora biblioteci proceduri sau macrodefiniţii.
În continuare se prezintă schema logică a programului:

START

Preluare date de la tastatură sau din fişere;


Construire matrice emigrare/imigrare;

Calcul indicatori statistici


Apel proceduri sau macrodefiniţii

Afişare indicatori

STOP

Figura 1: Schema logică generală a programului.

Aceasta este schema logică generală a programului, ea fiind


detaliată la nivelul fiecărei proceduri sau macrodefiniţii în parte.

15
6. Proiectarea structurii produsului software
Se consideră că este nevoie să se lucreze cât mai modularizat. Se
construiesc trei librării de proceduri şi macrodefiniţii. Unele librării sunt
doar de macrodefiniţii şi aceleaşi librării sunt construite şi numai din
proceduri. Se face acest lucru în vederea comparării performanţelor
programului în cazul în care foloseşte macrodefiniţii şi în cazul în care
foloseşte doar proceduri.
Structura celor trei librării fiind următoarea:
• bibliotecă de proceduri pentru conversia real-ASCII şi alte
proceduri utile în calculul indicatorilor statistici;
• bibliotecă de proceduri pentru lucru cu fişiere folosind
intreruperea 21h, aceeaşi bibliotecă fiind rescrisă şi cu
ajutorul macrodefiniţiilor;
• bibliotecă de proceduri folosită pentru afişarea şirurilor de
carctere şi preluarea de date de la tastatură, formatare
ecran.

Opţional se construieşte şi o bibliotecă de macrodefiniţii sau


proceduri pentru afişarea meniului text sau grafic precum şi o bibliotecă
pentru validarea datelor de intrare. Codul sursă pentru crearea şi
utilizarea meniului este conţinut în programul principal.
Pentru fiecare procedură sau macrodefiniţie din oricare bilbliotecă
se poate construi o schemă logică şi explica în detaliu dar fiind multe
asemenea construcţii, acestea sunt explicate împreună cu codul sursă
aferent în anexele acestui material.
Deci structura produsului software elaborat pentru rezolvarea
problemei este următoarea: trei biblioteci de macrodefiniţii şi proceduri şi
un program principal din care se apelează funcţiile din cele trei librării.
Se creează o structură arborescentă a programului pentru a
observa structura sa modulară în Figura 2:

16
Program Principal
(MAIN)

Introducere date Efectuare Calcule Afisare rezultate


(INTRD) (CALC) (AFISR)

Indicatori individuali Indicatori agregati


(CALCF) (CALCG)

Figura 2: Structura arborescentă a programului.

Apelul procedurilor sau macrodefiniţiilor din aceste librării se


face dintr-un program principal, program ce va fi prezentat parţial în
Capitolul 7 al acestei lucrări.
Codul sursă în limbaj de asamblare al bibliotecilor de
macrodefiniţii şi proceduri se află în Anexa 1 a prezentului material.

17
7. Textul sursă al programului
După parcurgerea tuturor paşilor anteriori se va trece la scrierea
codului sursă a programului.
Se includ bibliotecile cu macrodefiniţii care sunt folosite în
program:
include FMacro.mac
include IO.mac
apoi se trece la scrierea propriu-zisă a codului. Programul este împărţit în
trei segmente, segmentul de stivă, de date şi de cod. În segmentul de cod
se observă 2 mari porţiuni, o porţiune în care se implementează o parte
din procedurile folosite şi o parte în care este codul meniului şi apelul
macrodefiniţiilor şi procedurilor necesare calcului indicatorilor.
Sunt prezentate porţiuni din segmentul de stivă şi date:

.model large
.stack 1024
.data
vectjud dw 5 dup ('IF','CT','GL','CJ','TM')
;definire vector de judete-doar 5
matrdate dw 5 dup (5 dup (0))
;definire matrice de date, in varianta

;extinsa este de dd (elemente de patru octeti)


vecttemp dd 6 dup(1)
;vector temporar pentru sumele de pe linii si de pe
;coloane
CRLF db 13,10,'$'
sir_inc1 db '[1]Preluare date tastatura',10,13,'$'
sir_inc2 db '[2]Preluare date din fisier',10,13,'$'
sir_calc db '[3]Calcul indicatori statistici',10,
13,'$'
sir_afis db '[4]Afisare/Salvare indicatori',10,13,'$'
sir_ies db '[5] IESIRE',10,13,'$'
sir_opt db '-->$'
sir_temp db 7 dup(0),'$'
cod dw 0
numef db
'D:\Cristian\School\Articole\GhidPr~1\ghid\matr01.txt
','$'

i dw 5

18
j dw 5
col dw 5

Se observă că în segmentul de date se declară structura în care se


reţin numele judeţelor cu care se operează. Pentru viitoarele versiuni ale
programului datorită faptului că nu se va cunoaşte numărul de judeţe cu
care se va opera această structură nu va mai fi un masiv unidimensional
ci o listă simplu sau dublu înlănţuită. Matricea în care se reţin datele cu
care se operează – matrdate – dacă se operează cu date de dimensiuni
foarte mari poate avea alt tip mai cuprinzător. Apoi sunt declarate
variabile contor sau şiruri de caractere care vor fi utilizate în afişarea
meniurilor.
În continuare se prezintă porţiuni din segmentul de cod.

.code

;;;;Sectiune proceduri

;Procedura pentru efectuarea sumei pe linii din matrice


;Imaginea stivei inainte de apel trebuie sa fie
;distanta fata de BP in bytes
;adresa mica col 0
; i 2
; j 4
; mat 6 FAR
; vect 10 FAR
;i->numarul efectiv de linii al matricei
;j->numarul de coloane al matricei
;REZULTAT: [vects+i*4]=suma elementelor de pe linia i
;[vects]->de tip double dd
;[adr]->inseamna continutul de la adresa adr
sum_lin1 proc far
push bp
mov bp,sp
add bp,6
push SI
push DI
push AX
push BX
push CX
push DX
push ES

mov AX,2
mul word ptr [bp+2]
mov word ptr [bp+2],AX

19
;pentru ca se lucreaza pe word

mov AX,2
mul word ptr [bp+4]
mov word ptr [bp+4],AX
;pentru ca se lucreaza pe word

mov SI,0
;initializare contor i
linnextSI:
mov DI,0
;initializare contor j
;se pune in BX offset vector rezultate
mov BX,[BP+10]
;se pune in BX segment vector rezultate
mov ES,[BP+12]
mov AX,0
add BX,SI
add BX,SI
;pentru ca vectorul e dd
mov ES:[BX],AX
;initializare valoare rezultat pe linia i
linnextDI:
mov AX,SI
mul word ptr [BP] ;i*col
add AX,DI ;AX=i*Col+j
mov BX,[BP+6]
mov ES,[BP+8]
add BX,AX
mov AX,ES:[BX]
;de abia acum se acceseaza a[i][j]
mov CX,0
mov BX,[BP+10]
mov ES,[BP+12]
mov BX,SI
mov BX,SI
add ES:[BX],AX
adc ES:[BX+2],CX
add di,2
cmp DI,[BP+4]
jne linnextDI
add SI,2
cmp SI,[BP+2]
jne linnextSI
;restaurare registri
pop ES
pop DX

20
pop CX
pop BX
pop AX
pop DI
pop SI
pop BP
retf 14
sum_lin1 endp

;Procedura pentru efectuarea sumei pe coloane din matrice


;Imaginea stivei inainte de apel trebuie sa fie
;distanta fata de BP in bytes
;adresa mica col 0
; i 2
; j 4
; mat 6 FAR
; vect 10 FAR
;i->numarul efectiv de linii al matricei
;j->numarul de coloane al matricei
;REZULTAT: [vects+i*4]=suma elementelor de pe linia i
;[vects]->de tip double dd
;[adr]->inseamna continutul de la adresa adr
sum_col1 proc far
push bp
mov bp,sp
add bp,6
push SI
push DI
push AX
push BX
push CX
push DX
push ES

mov AX,2
mul word ptr [bp+2]
mov word ptr [bp+2],AX
;pentru ca se lucreaza pe word
mov AX,2
mul word ptr [bp+4]
mov word ptr [bp+4],AX
;pentru ca se lucreaza pe word
mov DI,0
;initializare contor i
colnextDI:

21
mov SI,0
;initializare contor j
mov BX,[BP+10]
;se pune in BX offset vector rezultate
mov ES,[BP+12]
;se pune in BX segment vector rezultate
mov AX,0
add BX,DI
add BX,DI
;pentru ca vectorul e dd
mov ES:[BX],AX
;initializare valoare rezultat pe linia i
colnextSI:
mov AX,SI
mul word ptr [BP] ;i*col
add AX,DI ;AX=i*Col+j
mov BX,[BP+6]
mov ES,[BP+8]
add BX,AX
mov AX,ES:[BX]
;de abia acum se acceseaza a[i][j]
mov CX,0
mov BX,[BP+10]
mov ES,[BP+12]
mov BX,DI
mov BX,DI
add ES:[BX],AX
adc ES:[BX+2],CX
add SI,2
cmp SI,[BP+2]
jne colnextSI
add DI,2
cmp DI,[BP+4]
jne colnextDI
;restaurare registri
pop ES
pop DX
pop CX
pop BX
pop AX
pop DI
pop SI
pop BP
retf 14
sum_col1 endp

;Procedura pentru citirea unei matrice dintr-un fisier


;Imaginea stivei inainte de apel trebuie sa fie

22
;distanta fata de BP in bytes
;adresa mica col 0
; i 2
; j 4
; mat 6 NEAR
; nume 8 NEAR
; cod 10 NEAR
;i->numarul efectiv de linii al matricei
;j->numarul de coloane al matricei; nume=numele
;fisierului; cod=0 nici o eroare
;REZULTAT: [vects+i*4]=suma elementelor de pe linia i
;[vects]->de tip double dd
;[adr]->inseamna continutul de la adresa adr
fis_read proc far
push bp
mov bp,sp
add bp,4
push SI
push DI
push BX
push CX
push DX

mov DX,[BP+8]
mov AH,3Dh
mov AL,0
int 21h
mov cx,ax ;handlerul pentru fisier
jnc TMP1rerr ;eroare la deschidere
jmp rerr
TMP1rerr:
mov AH,3fh ;citire i
mov BX,CX
mov DX,[BP+2] ;offset i
mov CX,2
int 21h
jnc TMP2rerr
jmp rerr
TMP2rerr:
mov CX,BX
helpi:
mov BX,DX ;offset i
mov byte ptr [BX+1],0
;byte-ul superior este 0
mov AH,3Fh ;citire j
mov BX,CX
mov DX,[BP+4] ;offset j
mov CX,2

23
int 21h
jc rerr
mov CX,BX
helpj:
mov BX,DX ;offset j
mov byte ptr [BX+1],0
;byte-ul superior este 0
mov AX,2
mov BX,[BP+2] ;offset i
mul word ptr [bx]
mov word ptr [bx],AX
;pentru ca se lucreaza pe word
mov AX,2
mov BX,[BP+4]
mul word ptr [bx] ;offset j
mov word ptr [bx],AX
;pentru ca se lucreaza pe word
mov SI,0
rfisnextSI:
mov DI,0
rfisnextDI:
mov AX,SI
mul word ptr [bp] ;i*Col
mov BX,[bp+6]
;i*Col+j;adresa matrice
add DX,BX ;a[i][j]
;citire din fisier
mov BX,CX
mov AH,3Fh
mov CX,2
int 21h
mov CX,BX
jc rerr

add DI,2
mov BX,[BP+4] ;offfset j
cmp DI,[BX]
jne rfisnextDI
add SI,2
mov BX,[bp+2] ;offset i
cmp SI,[BX]
jne rfisnextSI
mov DX,0
;necesar la impartire
mov BX,[BP+2] ;offset i
mov AX,[BX]
mov CX,2
div CX

24
mov [BX],AX
;restaurare valoare a lui i
mov bx,[bp+10] ;offset cod
mov AX,0
mov [BX],AX ;nici o eroare cod = 0

mov AH,3Eh ;inchidere fisier


mov BX,CX
int 21h
jc rerr
jmp rfisSF
rerr:
mov BX,[BP+10]
;se pune codul de eroare
mov [BX],AX
rfisSF:
;restaurare registri
pop DX
pop CX
pop BX
pop DI
pop SI
pop BP
retn 12
fis_read endp

start:
;MAIN
mov AX,@data
mov DS, AX

;;Sectiune cod - meniu


meniu:
StergeEcran
afis sir_inc1
afis sir_inc2
afis sir_calc
afis sir_afis
afis sir_ies
afis sir_opt
mov AH, 01h
int 21h
cmp AL,'1'
jne Pas1
jmp Opt1
Pas1:
cmp AL,'2'

25
jne Pas2
jmp Opt2
Pas2:
cmp AL,'3'
jne Pas3
jmp Opt3
Pas3:
cmp AL,'4'
jne Pas4
jmp Opt4
Pas4:
cmp AL,'5'
jne Pas5
jmp exit_dos
Pas5:
;s-a tastat altceva
jmp meniu

;optiunile

;S-a ales optiunea 1


Opt1:
;se citesc 25 de elemente ale matricei
push offset cod
push offset numef
push offset matrdate
push offset i
push offset j
push offset col
call fis_read
cmp cod,0
jne exit_dos
End_Opt1:
jmp meniu

;S-a ales optiunea 2


Opt2:
End_Opt2:
jmp meniu

;S-a ales optiunea 3


Opt3:
End_Opt3:
jmp meniu

;S-a ales optiunea 4


Opt4:
End_Opt4:

26
jmp meniu

exit_dos:
mov AX, 4C00h
int 21h
end start

Segmentul de cod este divizat în două mari părţi: o parte în care


se descriu procedurile folosite şi o parte în care aceste proceduri sunt
apelate. De asemenea urmărind codul sursă de la eticheta “start” – MAIN
– eniul poate fi folosit în orice program doar că trebuie schimbate şirurile
de caractere care sunt folosite pentru afişare. Aceste modificări au loc în
segmentul de date.
Se observă că în codul sursă prezentat în acest capitol este redat
doar scheletul programului principal, apelator adică meniul şi funcţia de
încărcare date din fişier. Apelul macrodefiniţiilor şi procedurilor pentru
calculul indicatorilor se face în mod similar doar că trebuie ştiut foarte
bine numărul de parametri şi ce parametri se transmit modulelor de
calcul. Programul sursă are multe comentarii astfel încât dacă cineva
doreşte să extindă facilităţile oferite de acest program să poată face acest
lucru într-un mod facil.

27
8. Crearea documentaţei aferente produsului
program
Documentaţia unui produs program trebuie să conţină: manualul
de utilizare, datele de test incluse in documentaţia de teste şi
implementare şi documentarea în amănunt a codului sursă şi explicarea
macrodefiniţiilor şi procedurilor care sunt folosite şi puse la dipoziţie
pentru dezvoltarile ulterioare. Documentarea produsului este foarte
importantă din mai multe puncte de vedere. Din punct de vedere
dezvoltare-scalabilitate este foarte important ca ceilalţi dezvoltatori să
înţeleagă foarte bine fiecare macrodefiniţie sau procedură pentru a creşte
gradul de reutilizare al codului. Din punct de vedere al beneficiarului este
foarte important manualul de utilizare în care sunt explicate toate
amănuntele din perspectiva interfeţei. Este explicată interfaţa grafică cu
utilizatorul, modul de configurare a anumitor fişiere şi de setare a
mediului de lucru. Chiar dacă interfaţa om-calculator este una intuitivă şi
prietenoasă documentarea pentru client este importantă. Acest manual de
utilizare nu trebuie să fie foarte tehnic decât când aplicaţia se adresează
unor specialişti. Documentarea macrodefiniţiilor, procedurilor, modulelor
de program şi programelor trebuie făcută dacă programul are posibilităţi
de extindere. Astfel se evită folosirea eronată a unor proceduri folosind
parametri incorecţi sau fiind nevoie de rescrierea acelei porţiuni de cod
care nu este înţeleasă, deoarece nu a fost documentată. Aşa cum l
limbajele evoluate există programe care generează automat fişierele
eferente fiecărei porţiuni de program – de exemplu javadoc din Java
Development Kit. Deci se poate stabili o convenţie ca de exemplu
comentariile de procedură să fie de 3 caractere “;” succesive. Apoi dacă
este parametru de intrare se scrie în codul sursă “param” urmat de spaţiu
şi numele parametrului de intrare, iar dacă este parametrul de ieşire, se
procedează la fel ca mai sus numai că se mai adaugă un semn distinct
“@” în faţă.
De exemplu, la macrodefiniţia de ştergere un fişier forma
generală este următoarea:

28
Macrodefiniţie pentru ştergerea unui fişier

Salvare regiştrii

Prelucrări

Restaurare regiştri

Figura 3: Schema generală a macrodefiniţiei pentru ştergerea unui fişier.

Pentru generarea automată a documentaţiei cu ajutorul unui


program creat de utilizator se vor scrie comentariile în următorul mod:
;;;Macrodefinitie pentru stergere fisier
;;;param NumeF: sir ASCIIZ ce contine numele
fisierului
;;;@param Rez: rezultatul operatiei: 0 succes,
altfel codul de ;;;eroare
StergeFisier MACRO NumeF, Rez
local NOK, Iesire
push AX
push DX
push DS
mov AH, 41h
lea DX, NumeF
int 21h
jc NOK
mov Rez, 0
jmp Iesire
NOK:
mov Rez, AX
Iesire:
pop DS
pop DX
pop AX
ENDM

Apoi cu ajutorul unui program special care “ştie” convenţia


stabilită, acest fişier se pot genera pagini HTML în care vor fi prezentate
toate comentariile conform unui standard. După acest tip de manual se
urmăreşte mult mai uşor tipul de parametri care trebuiesc folosiţi în
proceduri şi macrodefiniţii, modul de apel şi uşurează mult munca de
dezvoltare a noilor programe care utilizează module din acest program.

29
Pentru programul de faţă se elaborează manual de utilizare care conţine
inclusiv date de test şi manualul în care este prezentată fiecare procedură
sau macrodefiniţie cu tipul parametrilor de intrare, parametrilor de ieşire
şi a codurilor de eroare utilizate. Dacă această muncă de documentare s-
ar face manual şi nu automat pe baza comentariilor introduse de
programatori, productivitatea dezvoltării programelor ar scădea
considerabil.

30
9. Testare şi implementare
Se iau toate datele de test. Mai întai se consideră cazurile extreme.
De exemplu nu poate exista pe diagonala principală elemente cu valoarea
0. Se convine de asemenea ca să nu se utilizeze numere negative în
matrice, deşi acestea ar putea avea o interpretare, se foloseşte convenţia
conform căreia pe linie sunt exprimate emigrările de populaţie iar pe
coloane imigrările. Programul se scrie în limbaj de asamblare specific
procesoarelor Intel şi AMD şi se rulează pe PC-uri. Compilatoarele cu
care s-a testat sunt TASM (Borland) şi MASM (Microsoft). La
documentaţia în care se includ informaţii privind implementarea trebuie
specificaţi paşi care trebuiesc a fi urmaţi pentru obţinerea programului
final. Se scrie codul sursă într-un fişier text. De exemplu, dacă se scrie un
program care evaluează o expresie cu cinci operanzi (x=a*b-c/d+e) vor
trebui urmăriţi paşi:
• se caută fişierul ce conţine codul sursă pentru evaluarea
acestei expresii;
• se compilează codul sursă;
• în cazul în care nu apare nici o eroare se trece la pasul
următor, dacă apar erori se reia primul pas;
• se link-editeză codul obiect al programului şi în caz că nu apar
erori se obţine programul executabil.

Codul sursă a programului de mai sus se regăseşte în Anexa 2 a


prezentului material. Este de preferat ca notaţiile folosite în documente
de analiză/proiectare şi în caietul de sarcini să se respecte şi în program.
Pe programul din Anexa 2 se explică pas cu pas ce se întâmplă cu
regiştri microprocesorului, memoria, indicatori de condiţie, etc.
În figura 4 este prezentată fereastra TurboDebugger-ului imediat
ce este încărcat programul.

31
Figura 4: Turbo Debugger imediat dupa incărcarea programului.

Acest program este lansat deobicei cu comanda td în MS-DOS


prompt iar primul parametru din linia de comandă în mod uzual este
fişierul executabil rezultat la paşi anteriori.
Se observă că ecranul este împărţit în mai multe regiuni:
• Regiunea din stânga sus conţine codul programului. Se
observă că numele variabilelor au fost înlocuite cu
numere, care reprezintă deplasamentele (offset) în cadrul
segmentului de date.
• Regiunea din stânga jos prezintă conţinutul segmentului
de date. Se apasă click dreapta cu mouse-ul pe acea zonă
şi se selectează opţiunea „Go to...”. Se inserează
„DS:000E”, adică deplasamentul 000E în cadrul
segmentului de date. Se observă că în stânga jos în figura
4 sunt octeţi exact în ordinea declarării în program adică a
este 04, b este 02, c este 06 şi aşa mai departe.
• Regiunea din dreapta sus conţine registrele procesorului şi
indicatorii de condiţie (registru de flags). Aici se urmăresc
efectele diferitelor instrucţiuni precum „mov”.
• Regiunea din dreapta jos prezintă conţinutul segmentului
de stivă; în acest caz nu s-a folosit stiva, deci conţinutul
acestei zone este nedefinit.

Pentru a rula pas cu pas programul se apasă tasta F7. De fiecare


dată se urmăresc toate modificările care au loc. Conţinutul registrului AX
la fiecare pas al execuţiei programului este prezentat în tabelul 4:

32
Tabel 4: Conţinutul registrului AX la rularea programului pas cu pas

Instrucţiunea Conţinut Observaţii


AX (hexa)
mov AX,@data 0C6E AX=@data
mov DS,AX 0C6E DS=AX
mov AL,a 0C04 AL=04, AH rămâne 0C, IP
devine 0008
mul b 0008 AX=4*2=8
mov t1,AL 0008 t1=AL
xor AX,AX 0000 AX=0, iar flags: Z=1, P=1
mov AL,c 0006 AL=06 dar AH=00
div d 0002 AL=6 div 3=2;AH=6 mod 3=0
mov t2,AL 0002 t2=AL
mov AL,t1 0008 AL=t1
sub AL,t2 0006 AL=AL-2=8-2=6
add AL,e 000F AL=AL+9=6+9=0F
mov x,AL 000F X=AL
mov AH,4c 4C0F AH=4C;AL=0F
int 21h 4C0F Ieşire

În figura 5 este prezentată fereastra programului td chiar după ce


s-a pus rezultatul expresiei în x.

Figura 5: Starea regiştrilor înainte de terminarea programului.

33
Se observă că registrul AX are valoarea 15 adică 0F, dar şi
variabila x are tot valoarea 15 la adresa DS:0015. Cu cât acest pas de
testare şi implementare este efectuat cât mai consecvent şi corect cu atât
erorile care pot apărea la utilizarea programului pot fi mai mici. Mai mult
cu ajutorul programului TurboDebugger se depistează deseori cauzele
unei erori care dacă nu ar fi fost acest program ar fi creat multe probleme
echipei de dezvoltare.

34
10. Analiză cantitativă şi calitativă
Cea mai la îndemână analiză este cea cantitativă. Prima dată se
masoară în octeţi mărimea fişierelor sursă. Apoi se măsoară dimensiunea
codurilor obiect, şi apoi cele executabile.
Următorul pas al analizei este viteza de execuţie a anumitor
porţiuni din program. Dacă programul este modularizat atunci se
calculează viteza de execuţie în secunde a unui modul pe diverse date de
intrare.
Dacă se consideră datele de intrare din tabelul 2 atunci rezultă
următoarele rezultate:

Tabel 5: Analiză cantitativă asupra unor programe assembler

Indicatori Program Program Program Observaţii


simplu calcul calcul
de migraţie migraţie
evaluare populaţie cu populaţie
expresie librării ce cu librării
aritmetic conţin ce conţin
ă macrodefiniţii proceduri

Marime cod 697 8226 8200 Este mult mai util


sursă (în calcularea numărului
de linii sursă
bytes) deoarece la mărimea
fişierului sursă intră
şi comentariile
Mărime cod 295 2804 1302 Primul program nu
obiect (în conţine nici o
macrodefiniţie sau
bytes) procedură.
Mărime cod 563 3100 1510
executabil (în
bytes)
Timp de 1 2 3 Doar pe modul de
execuţie (sec) calculează primul
indicator

35
Este evident din datele înregistrate că tipul de aplicaţie este
decisiv în alegerea de a lucra cu biblioteci de macrodefiniţii sau biblioteci
de proceduri.
De exemplu la o aplicaţie în care timpul este critic, eventual este
vorba despre o aplicaţie în timp real, dar memoria nu are limitări serioase
atunci se va opta pentru dezvoltarea de aplicaţii care folosesc
macrodefiniţii.
Dacă din contră spaţiul ocupat de codul executabil trebuie să fie
mic iar timpul de răspuns nu este restrictiv atunci se va opta pentru
dezvoltarea de programe utilizând biblioteci de proceduri.
La calculatoarele personale la aplicaţii de dimensiuni medii
rareori se pune problema de spaţiu de memorare a codului executabil.
Dar există acum foarte multe dispozitive „neconvenţionale”
(smart-card-uri, procesoare de telefoane mobile şi echipamente de
comunicaţii) au nevoie de aplicaţii în timp real care să ocupe şi puţină
memorie.
Atunci se caută un grad de optim de îmbinare a bibliotecilor
uzitate, adică se vor folosi biblioteci de macrodefiniţii în modulele critice
din punct de vedere timp de execuţie, iar în modulele critice din punct de
vedere spaţiu de stocare se vor utiliza biblioteci de proceduri.
Considerentele calitative se resfrâng în mod direct asupra
indicatorilor cantitativi. De exemplu calitatea programării, adică
optimizarea codului scris implică obţinerea unui cod executabil cu număr
optim de cicluri maşină. Acest lucru are influenţă directă asupra timpului
de execuţie a programului. Deci evident timpul de execuţie a programului
va scădea, dar mărimea codului executabil poate fi mai mare deoarece
instrucţiunile cu cicluri maşină mai puţine pot ocupa mai mulţi octeţi.
Aceste lucruri depind foarte mult şi de asamblorul folosit.

36
11. Concluzii
În rezolvarea problemelor este foarte importantă analiza
problemei. Dacă în perioada de analiză există erori care nu sunt tratate în
momentul în care apar modificări asupra algoritmului pot rezulta ieşiri
ale programului care nu mai pot fi controlate. Numărul de erori este de
obicei proporţional cu dimensiunea problemei de rezolvat, iar pentru a
evita astfel de eşuări se modularizează cât mai mult programul.
Alegerea tipul de date utilizat în rezolvarea programului este
foarte important. Depinde de foarte mulţi factori – limbajul de
programare sau asamblare care se foloseşte, tipul de maşină sau procesor
pe care se lucrează, compatibilitatea cu versiunile precedente – şi trebuie
avută în vedere scalabilitatea programului, posibilitatea lui de extindere.
De exemplu, dacă pentru un program utilizat într-o instituţie bancara se
poate folosi tipul de date pe 8 octeţi (dq) pentru memorarea sumelor de
bani, în momentul în care mai apar filiale şi programul trebuie
implementat şi în acele filiale – sumele cu care se operează fiind mult
mai mari – atunci este avantajos a se alege încă din perioada de analiză
posibilitatea de lucra cu numere memorate ca şiruri de caractere iar
operaţiile aritmetice şi logice să fie executate simulat.
Un alt lucru important este structurarea programului în module cât
mai independente pentru a putea fi dezvoltat în echipă. În acest sens
programul se structurează arborescent iar nodurile arborelui sunt fie
modulele care trebuiesc implementate fie funcţiile pe care trebuie să le
îndeplinească programul.
Specificaţiile elaborate de programator sau echipa de dezvoltare
trebuie să fie concise şi clare. Ele trebuie să conţină exemple de test.
Aceste exemple de multe ori nu sunt suficiente iar pentru creşterea
performanţelor dezvoltatorului de programe se recurge la următoarea
strategie:
• Producătorul lansează produsul în variantă beta;
• Produsul software este dat unui număr limitat de
utilizatori pentru a fi testat;
• Programul este testat cu datele de test ale utilizatorului pe
cazuri reale dar rezultatele trebuie înscrise într-un tabel cu
un anumit format;
• Conform rezultatelor colectate de la acei utilizatori care au
testat produsul – utilizatori au folosit programul gratuit
dar au realizat implicit şi trestarea produsului – produsul

37
software este lansat în varianta finală. Tabelele de teste au
un format standard în care sunt cuprinse informaţii ca:
tipul de maşină şi procesor pe care s-a testat programul,
data, cu ce date de test s-au obţinut ieşirile respective,
durata execuţiei, dacă se intră în ciclare infinită, etc.

Programatorul trebuie să respecte nişte reguli, convenţii şi


standarde pentru a evita scrierea de cod redundant şi care conţine erori.
De exmplu o convenţie folosită poate fi ca orice macrodefiniţie sau
procedură să depună codul de eroare în registrul AX iar dacă AX este 0
atunci operaţia s-a executat cu succes iar dacă nu este 0 atunci va conţine
un cod de eroare, codurile de eroare fiind comune pentru toată echipa de
dezvoltare. O altă regulă este ca transmiterea parametrilor în procedură să
se facă numai pe stivă. Pot fi stabilite convenţii chiar şi pentru scrierea
codului sursă, de exemplu regiştrii fiind scrişi cu literă mare. Dacă se
lucrează în echipă acest mod de abordare este esenţial, fiind necesară o
coerenţă în dezvoltarea produsului.

38
Anexa 1

1. Bibliotecă de macrodefiniţii (FileMacro.mac) pentru lucru cu


fişiere:

;Macrodefinitie pentru creare fisier


;Parametrii de intrare:
; NumeF: sir ASCIIZ ce contine numele fisierului
; Atrib: atribute de creare ale noului fisier:
; 0 fisier normal
; 1 fisier protejat la scriere
; 2 fisier ascuns
; 4 fisier de sistem
;Parametrii de iesire:
; Handler: indicator de fisier returnat sau -1 la
;eroare
; Rez: rezultatul operatiei: 0 succes, altfel codul
;de eroare
CreeazaFisier MACRO NumeF, Atrib, Handler, Rez
local NOK, Iesire
push AX
push CX
push DX
push DS
mov AH, 3Ch
mov CX, Atrib
lea DX, NumeF
int 21h
jc NOK
mov Handler, AX
mov Rez, 0
jmp Iesire
NOK:
mov Handler, -1
mov Rez, AX
Iesire:
pop DS
pop DX
pop CX
pop AX
ENDM

;Macrodefinitie pentru deschidere fisier

39
;Parametrii de intrare:
; NumeF: sir ASCIIZ ce contine numele fisierului
; Acces: tipul de acces:
; 0 citire
; 1 scriere
; 2 citire/scriere
;Parametrii de iesire:
; Handler: indicator de fisier returnat sau -1 la
;eroare
; Rez: rezultatul operatiei: 0 succes, altfel codul
;de eroare
DeschideFisier MACRO NumeF, Acces, Handler, Rez
local NOK, Iesire
push AX
push DX
push DS
mov AH, 3Dh
mov CX, Acces
lea DX, NumeF
int 21h
jc NOK
mov Handler, AX
mov Rez, 0
jmp Iesire
NOK:
mov Handler, -1
mov Rez, AX
Iesire:
pop DS
pop DX
pop AX
ENDM

;Macrodefinitie pentru inchidere fisier


;Parametrii de intrare:
; Handler: identificatorul de fişier returnat de
;funcţia de creare/deschidere
;Parametrii de iesire:
; Rez: rezultatul operatiei: 0 succes, altfel codul
;de eroare
InchidereFisier MACRO Handler, Rez
local NOK, Iesire
push AX
push BX
mov AH, 3Eh
mov BX, Handler
int 21h
jc NOK

40
mov Rez, 0
jmp Iesire
NOK:
mov Rez, AX
Iesire:
pop BX
pop AX
ENDM

;Macrodefinitie pentru scriere in fisier


;Parametrii de intrare:
; Handler: identificatorul de fisier returnat de
;functia de creare/deschidere
; Buffer: zona de memorie din care se vor scrie
;datele citite
; OctetiDeScris: numarul de octeti de scris
;Parametrii de iesire:
; OctetiScrisi: numarul de octeti scrisi
; Rez: rezultatul operatiei: 0 succes, altfel codul
;de eroare
ScrieInFisier MACRO Handler, Buffer, OctetiDeScris,
OctetiScrisi, Rez
local NOK, Iesire
push AX
push BX
push CX
push DX
mov AH, 40h
mov BX, Handler
lea DX, Buffer
mov CX, OctetiDeScris
int 21h
jc NOK
mov OctetiScrisi, AX
mov Rez, 0
jmp Iesire
NOK:
mov Rez, AX
Iesire:
pop DX
pop CX
pop BX
pop AX
ENDM

;Macrodefinitie pentru citire din fisier


;Parametrii de intrare:

41
;Handler: identificatorul de fisier returnat de functia de
;creare/deschidere
;Buffer: zona de memorie in care se vor scrie datele citite
; OctetiDeScris: numarul de octeti de citit
;Parametrii de iesire:
; OctetiScrisi: numarul de octeti scrisi
;Rez: rezultatul operatiei: 0 succes, altfel codul ;de
;eroare
CitesteDinFisier MACRO Handler, Buffer, OctetiDeCitit,
OctetiCititi, Rez
local NOK, Iesire
push AX
push BX
push CX
push DX
mov AH, 3Fh
mov BX, Handler
lea DX, Buffer
mov CX, OctetiDeCitit
int 21h
jc NOK
mov OctetiCititi, AX
mov Rez, 0
jmp Iesire
NOK:
mov Rez, AX
Iesire:
pop DX
pop CX
pop BX
pop AX
ENDM

;Macrodefinitie pentru stergere fisier


;Parametrii de intrare:
; NumeF: sir ASCIIZ ce contine numele fisierului
;Parametrii de iesire:
; Rez: rezultatul operatiei: 0 succes, altfel codul
;de eroare
StergeFisier MACRO NumeF, Rez
local NOK, Iesire
push AX
push DX
push DS
mov AH, 41h
lea DX, NumeF
int 21h
jc NOK

42
mov Rez, 0
jmp Iesire
NOK:
mov Rez, AX
Iesire:
pop DS
pop DX
pop AX
ENDM

;Macrodefinitie pentru pozitionare in fisier


;Parametrii de intrare:
; Handler: identificatorul de fisier returnat de
;functia de creare/deschidere
; Pozitie: numarul de octeti fata de punctul de
;referinta (inceput, curent, sfarsit)
; From: punctul de referinta:
; 0 fata de inceputul fisierului
; 1 fata de pozitia curenta in fisier
; 2 fata de sfarsitul fisierului
;Parametrii de iesire:
; PozCrt: noua pozitie in fisier
; Rez: rezultatul operatiei: 0 succes, altfel codul
;de eroare
PozitionareInFisier MACRO Handler, Pozitie, From, PozCrt,
Rez
local NOK, Iesire
push AX
push BX
push CX
push DX
mov AH, 42h
mov AL, From
mov BX, Handler
mov DX, word ptr Pozitie[0]
mov CX, word ptr Pozitie[1]
int 21h
jc NOK
mov word ptr Pozitie[0], AX
mov word ptr Pozitie[1], DX
mov Rez, 0
jmp Iesire
NOK:
mov Handler, -1
mov Rez, AX
Iesire:
pop DX
pop CX

43
pop BX
pop AX
ENDM

2. Biblioteca de macrodefinitii (IO.mac) pentru lucru cu siruri de


caractere:

;Macrodefinitie pentru stergerea ecranului


StergeEcran MACRO
push AX
mov AL,02h
mov AH,00h
int 10h
pop AX
ENDM

;Macrodefinitie pentru citirea unui caracter de la


;tastatura
citc MACRO car
push AX
mov AH,01h
int 21h
mov car,AL
pop AX
ENDM

;Macrodefinitie pentru citirea unui sir de caractere de


;max. 20 caractere de la tastatura
cit MACRO buf
local et1, et2
push AX
push CX
push BX
lea BX, buf
mov CX,20
xor SI,SI
et1:
jcxz et2
mov AH,01h
int 21h
cmp AL,13h
je et2
mov AH,0
mov BX[SI],AX
dec CX
inc SI
jmp et1

44
et2:
mov BX[SI], word ptr ’$’
mov DL,13
mov AH,02h
int 21h
mov DL,10
mov AH,02h
int 21h
pop BX
pop CX
pop Ax
ENDM

;Macrodefinitie pentru citirea unui sir de numere


;citirea se opreste cand se introduce orice altceva decat
;un numar
citsn MACRO sir
local etr, et1
push DS
push BX
push AX
push DX
lea BX, sir
etr:
mov AH,08h
int 21h
cmp AL,'9'
jg et1
cmp AL,'0'
jb et1
mov [BX],AL
mov DL,AL
mov AH,02h
int 21h
inc BX
jmp etr
et1:
mov byte ptr[BX],'$'
mov DL,13
mov AH,02h
int 21h
mov DL,10
mov AH,02h
int 21h
pop DX
pop AX
pop BX
pop DS

45
ENDM

;Macrodefinitie pentru afisarea unui sir de caractere


afis MACRO sir
local etr, et1
push DS
push DX
push AX
lea DX, sir
mov AH,09h
int 21h
pop AX
pop DX
pop DS
ENDM

;Macrodefinitie pentru conversie ASCII-binar


;parametri – numar:DB, num:DD, baza:DW
;numărul se află în AX - EAX
atoi MACRO numar,num,baza
local etsf, rev
push DS
push SI
push EAX
push EBX
lea SI,numar
xor EAX,EAX
xor EBX,EBX
rev:
mov BL,[SI]
cmp BL,’$’
jz etsf
sub BL,30h
mul baza
add EAX,EBX
inc SI
jmp rev
etsf:
mov num, EAX
pop EBX
pop EAX
pop SI
pop DS
ENDM

46
;Macrodefinitie pentru conversie binar-ASCII
;si afisare
;parametri – numarul este preluat din nr DD
afisn MACRO nr,baza
local rel,etc,etsf
push BP
push SP
push EAX
push EDX
mov BP,SP
mov EAX,nr
rel:
xor DX,DX
or EAX,0
jz etc
div baza
add EDX,30h
push EDX
jmp rel
etc:
cmp BP,SP
jz etfs
pop EDX
mov AH,02h
int 21h
jmp etc
etsf:
mov num, EAX
pop BX
pop AX
pop SI
pop DS
ENDM

47
Anexa 2

;Program de evaluare a expresiei matematice x=a*b-c/d+e

.model small ;definire model de memorie


.data ;definire segment de date
a db 4 ;definire variabile
b db 2
c db 6
d db 3
e db 9
t1 db ? ;definire rezultate
t2 db ?
x db ?
.code ;definire segment de cod
start: ;etichetă de început
mov ax,@data ;initializare segment de date
mov ds,ax
mov al,a ;al=a
mul b ;al=al*b
mov t1,al ;t1=a1
xor ax,ax ; ax=0
mov al,c ;al=c
div d ;al=al div d
mov t2,al ;t2=al
mov al,t1 ;al=t1
sub al,t2 ;al=a1-t2
add al,e ;al=al+e
mov x,al ;x=al
mov ah,4Ch ;4Ch cod serviciu
int 21h ;apel intrerupere DOS
end start ;sfarsit program

48
Anexa 3

Probleme propuse pentru realizarea proiectelor la disciplina limbaje de


asamblare.

1. Indicele sintetic al preţurilor de tip Paasche.


2. Calculul indicatorului static ritm
3. Masa monetară
4. Calculul productuivităţii medii zilnice la nivelul unei întreprinderi
5. Calculul estimatorului A din ecuaţia de regresie
6. Calcularea procentului de modificare a producţiei fizice totale
7. Calculul fondului de timp calendaristic
8. Profitul mediu la 1 leu cifră de afaceri
9. Nivelul mediu al productivităţii muncii la nivelul economiei
naţionale
10. Calculul ritmului încasărilor lunare
11. Impactul taxelor pe cantitate asupra restricţiei de buget
12. Calculul mediei şi dispersiei dintr-o serie de date
13. Calculul duratei medii a zilei de lucru la nivelul unei întreprinderi
14. Calculul ratei rentabilităţii resurselor consumate
15. Calculul indicelui de lichiditate
16. Calculul indicilor de tip LasPeyres şi Paasche pentru analiza
modificării valorii vânzărilor sub influenţa factorilor preţul şi
cantitatea
17. Calculul salariului mediu
18. Câştigul potenţial al titlurilor financiare
19. Indicele producţiei valorice
20. Productivitatea marginală
21. Calculul salariului net
22. Calculul suprafeţei totale de depozitare
23. Lucru cu structuri dinamice de date – liste, arbori.
24. Calcularea indicelui de preţ la consumatori
25. Efectul de substituţie şi efectul de venit de tip Slutsky
26. Calculul cotei de piaţă
27. Calculul rtmului modificărilor relative
28. Calculul rezultatului exerciţiului contabil al unei firme prin contul
de profit şi pierdere

49
29. Realizare repartiţiilor bazate pe generarea secvenţelor de numere
aleatoare cu densitate de probabilitate f în probleme de simulare
economică
30. Calculul abaterii individuale

50
Bibliografie

[ATHA92] Irina Athanasiu, Alexandru Panoiu, „Microprocesoarele


8086, 286, 386”, Editura Teora, Bucureşti, 1992.
[IVAN96] Ion Ivan, Cristian Codreanu, „Optimizarea programelor
assembler”, ASE – Departamentul de Informatică
Economică, Bucureşti, 1996.
[IVAN97] Ion Ivan, „Designul limbajelor de asamblare”, revista
„Informatică Economică”, Nr.1/1997, Bucureşti.
[IVAN98] Ion Ivan, Cristian Codreanu, „Optimizarea programelor
assembler”, revista „Informatică Economică”, Nr.6/1998,
Bucureşti.
[IVAN98a] Ion Ivan, Marian Dârdală, Gabriel Şutac, Valentin
Dragomir, „Referirea datelor în structuri complexe prin
proceduri assembler”, revista „Informatică Economică”,
vol. III, Nr.7/1998, Bucureşti.
[IVAN99] Ion Ivan, Adrian Licuriceanu, Sebastian Teaciuc,
Gheorghe Lupu, „Aplicaţii orientate obiect în limbaje de
asamblare”, „Studii şi cercetări de calcul economic şi
cibernetică economică”, Nr.3/1999, Bucureşti.
[IVAN02] Ion Ivan, Paul Pocatilu, Doru Cazan, „Practica dezvoltării
software în limbaje de asamblare”, Editura Economică,
Bucureşti 2002.
[IVAN02a] Ion Ivan, Paul Pocatilu, Marius Popa, Cristian Toma,
„Semnătura electronică şi securitatea datelor în comerţul
electronic”, revista „Informatică Economică”, vol. VI,
Nr.3/2002, Bucureşti.
[MUSC97] Gheorghe Muscă, „Programare în limbaj de asamblare”,
Editura Teora, Bucureşti 1997.
[SOMN92] Dan Somnea, Vlăduţ Teodor, „Programarea în
assembler”, Editura Tehnică, Bucureşti 1992.

51