Documente Academic
Documente Profesional
Documente Cultură
Limbaj de Asamblare Ivan PDF
Limbaj de Asamblare Ivan PDF
Ion IVAN
Paul POCATILU
Doru CAZAN
Coordonatori
PRACTICA DEZVOLTRII
SOFTWARE
N
LIMBAJE DE ASAMBLARE
Editura Economic
Bucureti 2002
400
Colectivul de autori
Ilie ADRIAN
Laureniu ARICIU
Doru CAZAN
Cristian CODREANU
Valentin DRAGOMIR
Ion IVAN
Laur IVAN
Alexandru LEAU
Adrian LICURICEANU
Zsolt MARK
Teodor MIHAI
Paul POCATILU
Mihai POPESCU
Gabriel UTAC
Sebastian TCACIUC
Daniel VERNI
401
CUPRINS
1
2
Introducere
Caracteristicile limbajelor de asamblare
2.1 Prelucrri elementare
2.2 Caracterul neimplicit al definirilor si prelucrrilor
2.3 Secvenialitatea instruciunilor
2.4 Absena prioritilor
2.5 Contextul dinamic
2.6 Libera poziionare
2.7 Adresarea generalizat
2.8 Necompactitatea construciilor
2.9 Incluziunea
2.10 Concluzii
Reprezentarea informaiei
3.1 Codificarea informaiei
3.2 Organizarea datelor
3.3 Reprezentarea informaiei numerice
3.4 Reprezentri ale irurilor de caractere
Moduri de adresare
4.1 Calculul adresei unui operand
4.2 Modul de adresare imediat
4.3 Modul de adresare registru
4.4 Adresarea direct
4.5 Adresarea indexat
4.6 Adresarea bazat
4.7 Adresarea bazat i indexat
11
13
13
14
16
17
19
20
21
23
24
25
27
27
28
30
36
39
39
41
43
44
45
47
48
402
5
10
11
12
49
53
53
55
56
56
61
61
63
65
71
77
78
81
81
82
82
84
88
89
90
91
95
95
95
96
99
102
103
107
107
109
112
117
117
119
120
122
129
131
131
131
134
138
145
147
147
403
13
14
15
16
17
149
151
153
155
156
157
157
163
165
165
166
168
172
173
179
179
179
182
187
189
190
193
195
195
196
198
199
201
203
204
205
205
206
207
207
209
210
211
213
213
215
221
231
235
235
404
18
19
20
21
22
23
242
251
253
253
257
260
276
282
289
289
296
300
304
306
307
316
318
319
319
320
323
327
329
330
331
332
334
334
335
336
338
339
339
340
342
344
345
347
347
349
351
359
364
365
365
366
405
23.3 Sistemul de operare MS-DOS
23.4 Resurse ale programelor rezidente
23.5 Controlul proceselor
23.6 Probleme specifice n realizarea programelor rezidente
23.7 Activarea programelor rezidente
23.8 Program rezident pentru afiarea ceasului
23.9 Concluzii
24
Programarea n modul protejat
24.1 Moduri de operare ale procesorului 80x86
24.2 Regitrii procesoarelor i386/i486
24.3 Moduri de gestiune a memoriei
24.4 Comutarea in modul protejat
24.5 Implementarea modului de lucru multitasking
24.6 Concluzii
25
Programarea aplicaiilor Windows n limbaj de asamblare
25.1 Interfaa de programare a aplicaiilor Windows
25.2 Organizarea memoriei in Windows 9x
25.3 ncrcarea programelor Win32
25.4 Structura unui program n limbaj de asamblare
25.5 Programarea sub Windows
25.6 Asamblarea si editarea de legturi
25.7 Exemplu de program Win32
Bibliografie
Anexe
A I Arhitectura procesoarelor din familia Intel 80x86
A II Mnemonicele instruciunilor procesorului 80x86
A III Setul de instruciuni ale procesoarelor Intel 80x86
A IV Regitrii coprocesorului 80x87
A V Mnemonicele instruciunilor coprocesorului 80x87
A VI Primul program n limbaj de asamblare
A VII Analiza comparat a utilizrii diferitelor tipuri de reprezentri
A VIII Calcul matriceal - studiu de caz
369
370
373
378
385
388
398
399
399
400
407
409
423
426
427
427
428
430
430
432
441
441
447
A-1
A-5
A-11
A-69
A-73
A-77
A-89
A-101
406
2
CARACTERISTICI ALE LIMBAJELOR DE
ASAMBLARE
2.1 Prelucrri elementare
Limbajele algoritmice de programare (FORTRAN, COBOL, PL/I,
ALGOL) i limbajele evoluate de programare (C++, PASCAL) conin construcii
care realizeaz prelucrri complexe. Compilatoarele lor dezvolt secvene cu multe
instruciuni n module obiect. n schimb, limbajele de asamblare conin prelucrri
elementare. Instruciunile lor sunt puse n coresponden cu operaii simple.
Instruciunea
add O1, O2
efectueaz copierea operandului O2. Dup executarea ei, operandul O1 are acelai
coninut cu cel al operandului O2.
Instruciunea
shl O1,x
407
Instruciunea
Adunare
Scdere
nmulire
mprire
Comparare
Salt
necondiionat
Salt condiionat
ASSIRIS
MACRO-11
Limbaj asamblare
microprocesor
486
PENTIUM II
add
sub
mul
div
cmp
jmp
ad4, add
sb4, sbd
mp4, mpd
dv4, dvd
cp4, cp1
bru
add
sub
mul
div
cmp
br
add
sub
mul
div
cmp
jmp
add
sub
mul
div
cmp
jmp
beq, bne,...
408
cei doi operanzi sunt tratai ca ntregi binari. Dac programatorul nu a inclus n
program procedura de realizare a conversiei operandului B aceast operaie nu este
implicit, deci nu se efectueaz.
ntr-un limbaj algoritmic, dac operandul de tip ntreg A este iniializat cu
27, iar operandul B de tip zecimal mpachetat este iniializat cu 13, instruciunea:
C=A+B
se efectueaz prin parcurgerea pailor urmtori:
se convertete operandul B de la zecimal mpachetat la ntreg binar
00
13
00
0D
Temp B
1B
A
00
0D
Temp B
00
28
C
409
dw
dw
dw
27
0013h
?
ax, A
ax, B
C, ax
B:
A:
I1
I2
JMP A
I3
I4
I5
I6
I7
JZ B
I8
410
I1 I2 A1 A2 A3 I3 I4 B1 B2 I5 I6.
I1
I2
call A
I3
I4
call B
I5
I6
mov ax,4C00h
int 21h
A
proc
A1
A2
A3
Ret
endp
proc
B1
B2
ret
endp
411
se evalueaz astfel:
se incrementeaz b;
se nmulete a cu b;
se scade c;
se decrementeaz a.
Absena prioritilor operatorilor n limbajele de asamblare determin ca
ordinea de efectuare a operaiilor s fie cea indicat de succesiunea instruciunilor
n program. Astfel, dac se consider expresia:
a*b+c*d
i se construiete secvena:
mov
mul
add
mul
ax,a
b
c
d
ax,a
b
e,ax
ax,c
d
e,ax
sau:
(e=(e=(a*b))+(c*d))
412
dw
n instruciunea
add
a, 2
80
413
ax,[a]
operandul a este o variabil pointer care indic adresa unde se afl operandul care
particip ca termen la efectuarea adunrii.
n instruciunea
cmp
a+1,c
dw
dw
dw
3
5
?
ax,x
ax,y
z,dx
414
x
y
z
dw
dw
dw
3
5
?
...
mov
mov
add
mov
bx, bp
ax, [bx]
ax, [bx+2]
[bx+4], ax
.code
ax,@code
ds,ax
alfa
dw
3
dw
5
dw
?
mov
add
mov
ax,a
ax,y
z,ax
alfa:
415
n definirea:
.data
a
b
...
mov
mov
dw
dw
ax,a+200
bx,b-400
A[1]
A[100]
A[299] B[0]
B[1]
a+2
a+200
a+598
b+2
b-400
mov ax, a+200
mov
mov
inc
ax,5
ax,5
ax
atunci instruciunile:
inc
sau
add b, 01h
416
ax,7
se structureaz astfel:
b
b+1
b+2
00
07
cod operaie
Figura 2.6 Structura instruciunii mov ax,7
dei la asamblare pe baitul al treilea al instruciunii cu eticheta b se afl numrul 7
instruciunea:
mov
b+2,15
modific valoarea coninut de acest bait, iar rezultatul adunrii este 25 (10+15) i
nu 17 (10+7).
2.8 Necompactitatea construciilor
ntruct o instruciune efectueaz o operaie simpl i instruciunile se
organizeaz n secvene programul scris n limbaj de asamblare este vzut ca
secvene i nu ca expresii.
Mai mult, limitele de poziionare a instruciunilor n secvene reduc gradul
de compactare a programelor.
Dac n limbajul C++ expresia de atribuire multipl sau expresia virgul
permit creterea gradului de agregare cum o efectueaz i operatorul condiional, n
programele scrise n limbaj de asamblare acest grad de agregare nu este atins
datorit simplitii operaiilor cu care sunt asociate instruciunile.
Evaluarea expresiei:
m = min(a,b,c)
417
(ab) ? (bc) ? m=c: m=b:
(ac) ? m=c: m=a;
e1:
e2
...
mov
cmp
jle
mov
cmp
jle
mov
mov
...
ax,a
ax,b
e1
ax,b
ax,c
e2
ax,c
m,ax
2.9 Incluziunea
Pn la apariia limbajelor de programare din anii 70, limbajelor de
asamblare li se atribuiau o serie de caracteristici, dintre care se enumer:
accesul la toate resursele sistemelor de calcul (registre, funcii de baz,
memorie la nivel de bit);
posibilitatea de a efectua prelucrri imposibil de efectuat n limbaje
precum COBOL, FORTRAN din cauza modurilor de adresare i a
expresiilor de referire;
definirea de mecanisme specifice, particulare de referire a operanzilor i
operatorilor.
Odat cu apariia limbajelor C++, Pascal aceste bariere au disprut. Toate
prelucrrile specifice limbajelor de asamblare sunt incluse n limbajele C++ i
Pascal.
Instruciunilor inc i dec le corespund operatorii ++, respectiv --. Mai mult,
n limbajul C++ apar nuanrile de preincrementare, postincrementare,
predecrementare, postdecrementare.
Accesul la registre se efectueaz cu structura:
struct REGPACK
{
unsigned
unsigned
unsigned
};
418
419
3
REPREZENTAREA INFORMAIEI
Chiar dac un computer stocheaz diverse tipuri de informaie (texte,
imagini, sunete), aceast informaie este reprezentat intern ca informaie numeric.
Aceasta face ca o importan deosebit s fie acordat reprezentrii i prelucrrii
acestui tip de informaie.
3.1 Codificarea informaiei
Sistemele de calcul folosesc pentru prelucrarea i transmiterea
informaiei dou nivele de tensiune (de obicei 0V pentru 0 logic si +3.3V pn la
+5V pentru 1 logic). Cu aceste dou nivele de tensiune se reprezint cele dou
valori diferite, notate prin convenie cu 0 i 1, i care corespund cifrelor
sistemului de numeraie binar.
Binar
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
Octal
0
1
2
3
4
5
6
7
10
11
12
13
14
15
Hexazecimal
0
1
2
3
4
5
6
7
8
9
A
B
C
D
Tabelul 3.1.
Zecimal
0
1
2
3
4
5
6
7
8
9
10
11
12
13
420
1110
1111
16
17
E
F
14
15
421
Deoarece un singur bit este capabil s reprezinte doar dou valori diferite,
exist impresia c foarte puin informaie poate fi reprezentat cu ajutorul unui
bit. Dar nu este chiar aa! Se poate reprezenta cu ajutorul unui bit informaie
privitoare la valori de adevr (Adevrat sau Fals), la strile unui comutator (nchis
sau Deschis), la sexul unei persoane (Brbtesc sau Femeiesc), etc.
3.2.2 Nibble
Construcia nibble este un grup de patru bii. El prezint interes numai din
punctul de vedere al codificrii numerelor n format BCD (Binary-Coded Decimal)
i al reprezentrii numerelor hexazecimale. Cu ajutorul unui nibble se reprezint cel
mult 16 valori distincte.
Structura intern a unui nibble este:
b3
b2
b1
b0
b6
b5
b4
b3
b2
b1
b0
422
b8
b7
b6
b5
b4
b3
b2
b1
b0
423
Valoare
0
1
2
3
4
64
128
256
1024
Tabelul 3.2.
Reprezentare (n=2)
0000 0000 0000 0000
0000 0000 0000 0001
0000 0000 0000 0010
0000 0000 0000 0011
0000 0000 0000 0100
0000 0000 0100 0000
0000 0000 1000 0000
0000 0001 0000 0000
0000 0100 0000 0000
424
Valoare
0
1
2
3
-1
-2
-3
-4
-5
Tabelul 3.3.
Reprezentare (n=2)
0000 0000 0000 0000
0000 0000 0000 0001
0000 0000 0000 0010
0000 0000 0000 0011
1111 1111 1111 1111
1111 1111 1111 1110
1111 1111 1111 1101
1111 1111 1111 1100
1111 1111 1111 1011
425
07
00
05
00
04
00
03
00
01
un bait
Figura 3.4 Reprezentarea zecimal despachetat
Dac numerele se introduc de la tastatur ca ir de caractere ASCII, cifrele
numrului reprezentat zecimal despachetat se obin prin scderea numrului 30h
din codurile caracterelor.
Caracter
0
1
2
3
4
5
6
7
8
9
Tabelul 3.4.
Codul hexazecimal ASCII
30
31
32
33
34
35
36
37
38
39
07
05
04
03
01
un bait
Figura 3.5 Reprezentarea zecimal mpachetat
3.3.3 Reprezentarea numerelor reale
Reprezentarea numerelor reale se face n dou moduri distincte, i anume
reprezentare n virgul fix i reprezentare n virgul mobil, n funcie de modul
de reprezentare a prii ntregi i a prii fracionare a numrului.
426
Numr
semn
4823.493
0
-52.3
1
2.445
0
mii
4
0
0
sute
8
0
0
Tabelul 3.5.
Reprezentare
zeci uniti zecimi Sutimi Miimi
2
3
4
9
3
5
2
3
0
0
0
2
4
4
5
427
B6
B14
B22
E7
B5
B13
B21
E6
B4
B12
B20
E5
B3
B11
B19
E4
B2
B10
B18
E3
B1
B9
B17
E2
B0
B8
B16
E1
B6
B14
B22
B30
B38
B46
E2
E10
B5
B13
B21
B29
B37
B45
E1
E9
B4
B12
B20
B28
B36
B44
E0
E8
B3
B11
B19
B27
B35
B43
B15
E7
B2
B10
B18
B26
B34
B42
B50
E6
B1
B9
B17
B25
B33
B41
B49
E5
B0
B8
B16
B24
B32
B40
B48
E4
B6
B14
B22
B30
B38
B46
B54
B62
E6
E14
B5
B13
B21
B29
B37
B45
B53
B61
E5
E13
B4
B12
B20
B28
B36
B44
B52
B60
E4
E12
B3
B11
B19
B27
B35
B43
B51
B59
E3
E11
B2
B10
B18
B26
B34
B42
B50
B58
E2
E10
B1
B9
B17
B25
B33
B41
B49
B57
E1
E9
B0
B8
B16
B24
B32
B40
B48
B56
E0
E8
428
429
430
4
MODURI DE ADRESARE
4.1 Calculul adresei unui operand
Adresa fizic a unui bait este un numr natural. n funcie de dimensiunea
memoriei care se acceseaz sunt proiectate dimensiunile registrelor care stocheaz
informaia de adres.
Exist calculatoare care au n structur registre pe patru baii numite
registre de baz care stocheaz adresa de nceput a segmentului program, de
exemplu. Adunnd la aceast adres deplasamentul operandului se obine adresa lui
fizic. Numrul reprezentat pe 32 bii este suficient de mare, i nu mai necesit
artificii de combinare adres segment cu deplasament.
Exist tabele care concentreaz corelaia dintre lungimea expresiei de
adres n bii i lungimea maxim a zonei ce poate fi accesat. Astfel, cu adrese
definite pe 20 bii se pot accesa baiii ce formeaz o memorie de 1 MB.
Algoritmul pentru calculul de adres este format din operaii de deplasare
spre stnga i din adunri. Valoarea adresei apare ca o agregare a mai multor
elemente. Sunt rare cazurile cnd este impus proprietatea de dezagregare unic a
adresei, n componentele iniiale.
De cele mai multe ori, dezagregarea vizeaz determinarea deplasrii unui
operand avnd ca elemente de calcul adresa fizic i coninutul registrului segment,
adic adresa de nceput a segmentului.
Procesorul 286 de exemplu, ia n considerare pentru calculul de adres:
coninutul registrului segment (16 bii);
deplasarea operandului a crui adres se calculeaz (16 bii).
Prin deplasarea cu patru poziii spre stnga a coninutului registrului
segment i prin adugarea la noua valoare obinut a deplasrii operandului, se
obine adresa fizic a operandului.
De exemplu, registru segment DS are coninutul 00F0h, iar deplasarea
operandului este 000Ah. Deplasarea spre stnga cu 4 bii conduce la
00F00h + 000Ah=00F0Ah,
acest rezultat reprezint adresa fizic a operandului considerat.
431
Sk
d1
d2
B
d3
C
d4
D
432
unde:
a0 adresa de nceput a segmentului, coninut ntr-un registru
(CS, DS, ES);
ci coeficientul cu valoare unu dac tipul de deplasare relativ
i este definit (c1 corespunde deplasrii ca baz, c2
corespunde deplasrii variabile, c3 corespunde deplasrii
baitului asociat unei variabile); dac c0=c1=c2=c3=0
adresarea este imediat;
xi deplasarea de tip i; x1 este stocat ntr-un registru de baz,
x2 este stocat ntr-un registru index, iar deplasarea x3
este pus n coresponden cu numele unei variabile.
Expresiile de calcul ale adreselor prin valorile diferite ale coeficienilor c i
determin modurile de adresare.
Modul de adresare este definit ca algoritm de calcul al adresei absolute pe
baz de distane ale operanzilor.
Modul de adresare ofer posibilitatea implementrii att a structurilor
fundamentale de date (capacitatea de a referi elemente din matrice, linii din matrice
sau chiar matricea n ansamblul ei) ct i a structurilor de programare (structura
repetitiv este posibil numai utiliznd registrul de index, iar includerea de structuri
repetitive presupune i utilizarea unui registru de baz).
4.2 Modul de adresare imediat
Acest mod de adresare corespunde situaiei n care programatorul scrie
instruciuni de forma R-I, M-I, ca de exemplu:
mov
add
xor
mov
ax, 1ah
ax, 2
bx, 0fa00h
alfa, 500
cx, 4
si, 15
ax, 100
byte ptr[bx+1], 120
dx, 16
;b9
;83
;05
;c6
;ba
0004
ee 0f
0064
47 01 78
0010
433
ax,0
bx,100
alfa
bx,400
beta
bx,0ff0h
si,4
di,2
;iniializare registru
;comparare
;salt dac este la stnga intervalului
;comparare
;salt dac este la dreapta intervalului
;i pe bii registru bx cu masca 0ff0h
;incrementare registru si
;decrementare registru di
ax,200
ax,val_200
;14 cicluri
al, 2000
ax, 100
bx, 4000
434
ax,100
ax,c_100
100
ax
ax
ax
cx,ax
40h
50h
58h
91h
pune n eviden faptul c registrele prefixate sunt cele care influeneaz structura
codului fiecrei instruciuni.
Modul de adresare registru conduce la dezvoltarea n procesul de asamblare
a codurilor de instruciuni pe un bait (dac registrele sunt prefixate) sau pe doi baii
pentru combinaii oarecare de registre.
Unele dezvoltri de coduri sunt prezentate n secvena:
mov
mov
mov
shr
xor
sub
cs,ax
ds,ax
ss,ax
ah,cl
ax,ax
si,cx
8e
8e
8e
d2
33
2b
c8
d8
d0
ec
c0
f1
435
AX
4F
13
13
4F
x
Figura 4.2 La primul pas se face calculul adresei de memorie iar la al doilea pas
coninutul zonei de memorie este mutat n registrul AX
Secvena:
mov
mov
mov
add
sub
mov
add
ax, alfa
al, byte ptr beta
gama, dx
ax, sum
cx, ratia
ah, sir+2
sir-5, al
436
utilizeaz operanzii alfa, beta, gama, sum, ratia, ir, direct prin numele lor, tiind c
n procesul de asamblare acestor nume li se asociaz deplasri fa de adresa de
nceput a segmentului unde sunt definite.
Dac s-au definit i s-au alocat zone pentru operanzii din secvena:
00a0
00a2
00a4
00ac
a
b
c
e
dw
dw
dw
dw
10
20
30, 40, 10, 20
?
ax, a
ax, b
ax, c
ax, c+6
e, ax
ax, alfa+10*3-4
ax, beta
ciclu
437
cx,20
si,si
ax,ax
ax, x[si]
si
si
ciclu
si,si
ax,ax
ax,a[si]
si
si
si,2*(20-1)
ciclu
arat cum registrul index este folosit ca registru de control pentru gestionarea
ciclurilor.
n expresie poate lipsi deplasarea, caz n care registrul index trebuie pregtit
ca s refere corect elementele, ncrcnd adresa primului element ce se acceseaz.
Secvena:
mov
lea
xor
ciclu:
add
add
loop
cx,20
si,x
ax,ax
ax,[si]
si, 2
ciclu
438
1
BX
00
04
AX
FC
3
01
02
03
04
05
4A
4
4A
06
FC
07
08
09
0A
0B
0C
bp,
ax,
ax,
ax,
offset alfa
bp + 2
bp + 8
bp + 144
439
Secvena:
ciclul_1:
ciclul_2
xor
xor
xor
mov
push
mov
add
add
bx,
si,
ax,
cx,
cx
cx,
ax,
si,
bx
si
ax
nr_linii
nr_coloane
x [bx] [si]
2
440
loop
xor
pop
mov
shl
add
loop
ciclul_2
si, si
cx
dx, nr_coloane
dx,2
bx, dx
ciclul_1
1
BX
00
02
AX
2
00
01
E5
26
3
26
02
E5
03
04
si,
bx,
ax,
ax,
offset x
bx
ax
[bx + si]
441
ax, offset a
adr_a, ax
ax, offset adr_a
adr_adr_a, ax
ax, offset adr_adr_a
adr_adr_a, ax
bx, *** adr_adr_adr_a
pregtete mai nti variabilele pointer. Variabila pointer adr_a va conine adresa
operandului a. Variabila adr_adr_a va conine adresa variabilei pointer adr_a.
Variabila adr_adr_adr_a conine adresa variabilei pointer spre pointer spre variabila
a.
Ultima instruciune din secven are ca efect ncrcarea n registrul BX a
coninutului zonei de memorie (a) a crei adres se afl ntr-o zon de memorie
(adr_a), a crei adres la rndul ei se afl ntr-o zon de memorie (adr_adr_a), a
crei adres se afl n zona de memorie adr_adr_adr_a. Cele trei asteriscuri pun n
eviden c este vorba de o adresare indirect cu trei nivele de indirectare. Deci n
structura instruciunii, dac este adresare indirect, al localizarea operandului se va
specifica dac acesta este sau nu pointer, pentru a continua sau a ntrerupe procesul
de referire.
Adresarea indirect poate fi simpl, adresare indirect indexat i adresare
indirect bazat. Toate aceste mecanisme de indirectare pot fi implementate n
limbajele evoluate i cu setul de faciliti de evaluare a expresiilor de adres
existent acum la microprocesorul 80x86.
Expresiile de evaluare a adreselor pot fi dezvoltate mult n sensul
specificrii momentului n care intervin registrele index sau de baz. Astfel, se
poate proiecta un limbaj de asamblare n care expresia:
** alfa
bp
si
442
Mai nti folosind variabila alfa (acum alfa nu este o deplasare) se gsete
variabila ce conine o adres. La aceast adres se adaug coninutul zonei de
memorie a crei adres s-a aflat n registrul BP, obinndu-se o nou adres. Este
adresa unei zone de memorie ce conine o adres (al doilea nivel de indirectare). La
aceast adres se adaug coninutul registrului index i rezult adresa operandului
cu care se va lucra de fapt.
Fiecare mod de adresare este nsoit de un numr de cicluri main.
Alegerea unui anumit mod este dictat de structurile de date cu care se opereaz.
Expresia de adres, ca sum de un numr de termeni fixat se particularizeaz
funcie de codul specificat pe biii 2, 1, 0 ai baitului MODRM (v. capitolul
Instruciuni).
Modurile de adresare trebuie privite ca algoritmi de calcul ai expresiilor de
adres. Operanzii sunt registre sau numere, n final se obin adrese ale unor zone de
memorie al cror coninut este ntrebuinat fie pentru a iniializa, fie pentru a
modifica (prin adunare, scdere, deplasare, interschimb, conversie) un alt operand,
registru.
Indiferent care este procesorul cu care se lucreaz, programatorul n
limbajul de asamblare va cunoate restriciile de utilizare registre i structurile
posibile ale expresiilor de adres. Folosirea adecvat a unui mod de adresare se
pune n vedere prin lungimea textului scris i prin mulimea de instruciuni ce pot fi
nlocuite dac s-ar folosi un alt mod de adresare, mod care s-ar dovedi mai eficient.
443
5
INDICATORII DE CONDIIE
5.1 Registrul FLAGS
Procesoarele din familia x86 dispun de o serie de indicatori de condiie.
Acetia reprezint informaii legate de starea procesorului i efectul execuiei
instruciunilor. Fiecare indicator de condiie ocup 1 bit n cadrul unui registru
special, registrul F. Pentru microprocesorul 8086, structura acestui registru este cea
din figura 5.1.
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
-- -- -- -- OF DF IF TF SF ZF -- AF -- PF --
00
CF
444
Indicatorii CF, PF, AF, SF, ZF, TF i OF se mai numesc indicatori de stare;
DF este indicator de control, iar IF indicator de sistem.
Odat cu evoluia procesoarelor din gama x86, au fost introdui noi
indicatori. Astfel, la procesoarele 80386, registrul FLAGS este extins la 32 de bii,
formnd noul registru EFLAGS, a crui structur este reprezentat n figura 5.2.
<Registrul FLAGS pe 16 bii
->
31-18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0
VM RF 0 NT IO PL OF DF IF TF SF ZF 0 AF 0 PF 1 CF
445
31
PG
30-05
--
04
ET
03
TS
02
EM
01
MP
00
PE
446
447
Indicatorul
Instruciunea
AAA
AAS
AAD
AAM
DAA
DAS
ADC
ADD
SBB
SUB
CMP
CMPS
SCAS
NEG
DEC
INC
IMUL
MUL
RCL/RCR 1
RCL/RCR cont
ROL/ROR 1
ROL/ROR cont
SAL/SAR/SHL/SH
SAL/SAR/SHL/SH
SHLD/SHRD
BSF/BSR
BT/BTS/BTR/BTC
AND
OR
TEST
XOR
OF
SF ZF
------M
M
M
M
M
M
M
M
M
M
M
M
M
-M
-M
----0
0
0
0
--M
M
M
M
M
M
M
M
M
M
M
M
M
M
---
--M
M
M
M
M
M
M
M
M
M
M
M
M
M
---
M
M
M
--M
M
M
M
M
M
M
M
-M
M
M
M
Tabelul 5.1
AF P CF
F
TM -- M
TM -- M
-- M --- M -TM M TM
TM M TM
M M TM
M M M
M M TM
M M M
M M M
M M M
M M M
M M M
M M
M M
-- -- M
-- -- M
TM
TM
M
M
-- M M
-- M M
-- M M
-- -- --- -- M
-- M 0
-- M 0
-- M 0
-- M 0
448
OF SF ZF
AF
PF CF
----M
M
0
-M
M
-M
M
M
-M
M
-M
M
M
M
TM
--TM
M
M
--
-M
M
-M
M
M
M
--M
TM
M
0
---
---
M
--
---
---
-M
TF IF DF NT RF
0
0
0
M
M
M
M
M
M
M
M
M
M
M
M
M
--M
--
M
M
M
--
M
M
M
--
TM
TM
M
--
M
M
M
--
TM
TM
-M
---
---
---
---
-M
--
449
INS
INT
INTO
T
0
0
Indicatorul
OF SF ZF
Instruciunea
IRET
R
R R
Jcond
T
T
T
JCXZ
JMP
LAHF
LAR
M
LDS/LES/LSS/
LFS/LGS
LEA
LEAVE
LGDT/LIDT/LL
DT/LMSW
LOCK
LODS
LOOP
LOOPE/LOOP
T
NE
LSL
M
LTR
MOV
MOV control,
---debug
MOVS
MOVSX/MOV
ZX
MUL
NEG
NOP
NOT
OR
OUT
OUTS
POP/POPA
POPF
PUSH/PUSHA
/PUSHF
RCL/RCR 1
RCL/RCR
count
REP/REPE/R
EPNE
RET
ROL/ROR 1
ROL/ROR
count
SAHF
0
0
AF
PF CF
TF IF DF NT RF
R
T
R
T
--
--
-T
M
M
-M
-M
-M
-M
M
M
--
0
T
M
--
TM
TM
M
--
M
M
R
450
SAL/SAR/SHL
/SHR
1
SAL/SAR/SHL
/SHR count
SBB
SCAS
Indicatorul
Instruciunea
SET cond
SGDT/SIDT/S
LDT/SMSW
SHLD/SHRD
STC
STD
STI
STOS
STR
SUB
TEST
VERR/VERR
W
WAIT
XCHG
XLAT
XOR
M
-M
M
M
M
M
M
M
M
M
M
--M
M
M
M
M
M
OF SF ZF
AF
PF CF
--
--
M
M
TM
M
M
1
T
TF IF DF NT RF
1
1
T
M
0
M
M
M
M
M
M
--
M
M
M
0
--
451
6
INSTRUCIUNI
6.1 Clasificarea instruciunilor
Exist numeroase criterii de clasificare a instruciunilor, care nu se exclud.
Aceeai instruciune este identificat ca aparinnd unei grupe cel puin din fiecare
mprire a oricrui criteriu.
Dup numrul operanzilor instruciunile limbajului de asamblare se
grupeaz n:
instruciuni fr operanzi;
instruciuni cu un operand;
instruciuni cu doi operanzi;
instruciuni cu mai muli operanzi.
n mod uzual, instruciunile sunt proiectate cu un numr redus de operanzi,
ntruct creterea numrului de operanzi atrage mrirea gradului de complexitate al
instruciunii. n limbajul de asamblare o instruciune execut o operaie elementar,
cu nivel de complexitate redus.
Natura operanzilor grupeaz instruciunile n:
instruciuni de tip R-R, operanzii sunt registre;
instruciuni de tip R-M, un operand este registru, destinaia, iar
operandul surs, este n memorie;
instruciuni de tip M-R, operandul destinaie se afl n memorie,
operandul surs este un registru;
instruciuni de tip R-I, operandul surs este o constant imediat, iar
operandul destinaie este registru;
instruciuni de tip M-I, sursa este constant imediat, iar destinaia este
zon de memorie;
instruciuni de tip M-M, operanzii se afl n memorie.
Limbajele de asamblare se proiecteaz cu structuri de instruciuni care s
gestioneze numai o zon de memorie, deci instruciunile de tip M-M sunt rar
ntlnite sau excluse.
Lungimea zonei de memorie ocupat clasific instruciunile astfel:
instruciuni pe un bait, n care operanzii au poziie fixat, efectul este
unic;
instruciuni definite pe doi baii, de regul au ca operanzi registre;
452
453
unde:
- variabil de lucru;
- indic numrul de poziii cu care se face deplasarea spre
stnga; pentru valori diferite de 1, stocarea se va efectua n
registrul CL;
CF, OF
- indicatori de condiie;
High_Bit
- funcie care returneaz valoarea bitului cel mai
semnificativ al operandului.
Aceast instruciune are efectul nmulirii operandului cu 2 la puterea
CONTOR.
Reprezentarea sub form grafic a mecanismului unei instruciuni este
sugestiv, avnd ns pierderi de informaii de detaliu asupra modului n care
decurge realizarea operaiei. Pentru instruciunea
temp
CONTOR
n care Operand este registrul AL, reprezentarea grafic este dat n figura 6.1.
454
7
C
CF
AL
Figura 6.1. Deplasare spre stnga
SHL bx,1
SHL alfa,1
SHL ax,cl
SHL alfa,cl
SHL bx,5
SHL alfa,5
Tabelul 6.1.
Numr cicluri main
286
386
486
2
3
3
7
7
4
5+n
3
3
8+n
7
4
5+n
3
2
8+n
7
4
455
zon de memorie se vor face notaii adecvate. Restriciile noului limbaj, de cele
mai multe ori nu se regsesc n descrierile altor limbaje de asamblare pentru a
uura nvarea sau compararea lor.
Se va putea vorbi de o descriere bun a instruciunilor dac:
este prezentat mnemonica i semnificaia fiecrei litere;
printr-un text se specific operaia pe care o execut fiecare instruciune;
se detaliaz fiecare form de adresare a operanzilor admis i se
exemplific efectele pe care execuia instruciunilor le are asupra
operanzilor;
se specific numrul de cicluri main necesare execuiei fiecrei
variante de definire a expresiei de adresare a operanzilor;
se dau reprezentrile la nivel de bit ale dispunerii informaiilor din linia
surs, dup asamblare;
se precizeaz poziionarea indicatorilor de condiie.
Manualele care descriu limbaje de asamblare mbin toate modurile de
prezentare pentru a asigura att rigurozitate, ct i de a face limbajul de asamblare
mai atractiv, mai uor de nvat i de a utiliza ct mai potrivit instruciunile.
6.3 Forma extern a instruciunilor
Programul scris n limbaj de asamblare este format dintr-o succesiune de
instruciuni. Ceea ce scrie programatorul sunt forme concrete de prezentare a
instruciunilor sau forme externe.
O linie surs conine:
eticheta instruciunii (opional);
codul operaiei;
lista de operanzi;
comentariu (opional).
Regulile de construire a etichetelor sunt comune i pentru identificatori.
Lungimea cuvntului asociat etichetei este strict legat de dorina programatorului
de a da lizibilitate programului.
Dac se construiesc etichete cu o destinaie special, reutilizate ntr-un
context anume, este folosit caracterul blanc subliniat (underscore). Astfel,
construciile __alfa__ , _beta, gama _ sunt etichete din categoria menionat. n
programe se ntlnesc variabile globale definite n fiierele unor produse program
de larg circulaie, n expresii de adres.
n mod curent se definesc etichete precum: ciclu, start, final, adun, alege.
Pentru a mri lizibilitatea se fac concatenri de nume i delimitarea este obinut
prin utilizarea de litere mari. Astfel, etichetele AlegeMaxim, PretUnitar,
ExtrageBait, SirCifric, utilizate corespunztor mpreun cu comentariile de pe
fiecare linie ajut programatorul la depanarea sau la dezvoltarea programului.
456
Codul operaiei este de fapt o mnemonic. Programatorul care a lucrat ntrun limbaj de asamblare va observa c exist diferene minore la alctuirea
mnemonicelor. De aceea, cunoscnd un vocabular al operaiilor fundamentale,
generarea de mnemonice devine un proces natural.
n tabelul 6.2 sunt prezentate cteva din mnemonicele utilizate n timp
pentru operaiile cele mai frecvente din programe.
Tabelul 6.2.
Operaia
Addition
Move
Jump
Compare
Shift
Increment
Mnemonicele limbajelor
ASSEMBLERASSIRIS
IBM
A,AR,AD
AD4,AD8
MVC,MVI MVZ MVSR,MVSL
B
BRU
C,CD,CDR,CE
CP4,CP2
SLA,SRA
SLAx,SRAx
IC2,IC4
MACRO11
ADD
MOV
BR
CMP
ASL,ASR
INC
ASM
ADD
MOV
JMP
CMP
SAL,SAR
INC
se va instruciunea:
equ
equ
equ
15
a + 4*6
a + b
457
mov
ax, 135
ax, 11100b
pentru c NOT 10011b este egal cu 01100b, 01100b AND 10101b este egal cu
00100b, iar 00100b OR 11000b este egal cu 11100b.
La introducerea operatorilor relaionali este important s se cunoasc
valorile numerice cu care sunt puse n coresponden valoarea logic adevrat i,
respectiv, valoarea logic fals. n cazul asamblorului pentru limbaj ASM
adevrat nseamn (-1), iar fals nseamn (0). Operatorii relaionali sunt: GT (mai
mare ca), GE (mai mare sau egal), EQ (egal cu), NE (neegal), LT (mai mic dect),
LE (mai mic sau egal).
Instruciunea:
mov
bx,(7 gt 5)and(8 le 3)
db
dw
struc
dw
db
?
l0 dup (0)
?
8 dup (?)
458
str
alfa
ends
str 20 dup (<>)
struc
db
dw
dt
ends
st 10
?
?
?
; lungime 1
; lungime 2
; lungime 10
ax, type
bx, length
cx, size
mat ; ax=1+2+10
mat ; bx=50 (10*5 componente)
mat ; cx=50*13 baii rezervai.
mov
mov
mov
dd
12345678h
; ax=1234
; bx=5678
; al=56
459
dw
7
db
abcd
struc
db
?
dd
11 dup (?)
ends
c
10 dup ()
a este o variabil de tip cuvnt, b este variabil de tip bait, w este variabil de tip c.
Utilizarea numelui unei variabile nseamn asocierea cu ntreaga zon de memorie
alocat, 2 baii pentru variabila a, 1*4 baii pentru variabila b i 450 baii pentru
variabila w. Totui, orice variabil chiar dac are un tip, este privit ca zon de
memorie. Exist posibilitatea de a face conversii de tip aa fel nct variabila a
definit iniial ca un cuvnt s poat fi tratat ca un ir de 2 baii aa cum este
variabila b. Tot astfel se pune problema de a face o conversie ca variabila w s fie
privit fie ca un ir de cuvinte, fie ca un ir de baii. Conversia de tip presupune
utilizarea operatorului PTR ntr-o construcie de forma:
expresie_1
ptr
expresie_2
care realizeaz conversia de la tipul dat dup evaluarea expresiei-2 la tipul cerut de
expresia-1.
Dac se consider definirea:
aa
dd
12345678h
secvena:
mov
and
and
pune n eviden c dei variabila aa este definit dublu cuvnt se exploreaz din ea
numai un bait, presupunnd c registrul SI conine deplasamentul lui aa.
Operatorii SEG i OFFSET returneaz adresa de nceput a segmentului
unde se afl operandul, respectiv, deplasarea pe care o are operandul fa de
nceputul segmentului.
Dac o variabil xx este definit n segmentul de date SEGDAT,
iniializarea registrului de segment DS se efectueaz prin:
460
mov ax, seg xx
mov ds, ax
cx, xxx.alfa
Prioriti
1
2
3
4
5
6
7
8
9
10
11
12
13
Tabelul 6.3.
Operatori
() [] LENGTH, MASK, WIDTH
. (operatorul de referire membri din structuri)
HIGH, LOW
+,- (operatori unari)
: (specificare segment:offset)
OFFSET, PTR, SEG, THIS, TYPE
*, /, MOD, SHL, SHR
+,- (operatori binari)
EQ, NE, GT, GE, LT, LE
NOT
AND
OR, XOR
LARGE, SHORT, SMALL
461
462
Instruciune
Tabelul 6.4.
Numrul de apariii
mov
pop
cmp
push
sub
ret
add
jmp
call
lea
xor
567
152
89
77
32
28
20
14
6
6
4
7
c
6
c
5
c
4
c
3
c
2
c
1
c
0
c
registru
ax
cx
dx
463
bit
7
c
6
c
5
c
4
c
3
c
2
r
1
r
0
r
Cod
000
001
010
011
100
101
110
111
se va codifica astfel:
bit
7
0
c
6
1
C
5
0
c
4
0
c
3
0
c
2
1
r
1
1
r
0
0
r
464
7
c
6
c
5
c
4
c
3
c
2
c
1
d
0
w
7
m
6
m
5
R
4
R
3
R
1
r/m
465
Tabelul 6.6.
Biii 7, 6
Mm
00
01
10
11
Biii 2, 1, 0
000
001
010
011
100
101
110
111
Tabelul 6.7.
Formula de calcul a adresei
+
SI
+
deplasare
+
DI
+
deplasare
+
SI
+
deplasare
+
DI
+
deplasare
SI
+
deplasare
DI
+
deplasare
BP
+
deplasare
BX
+
deplasare
Deplasarea
BX
BX
BP
BP
se codific prin:
ba10h
Cei doi baii se interpreteaz astfel:
7 6 5 4 3 2 1 0
c c c c c c d w
1 0 1 1 1 0 1 0
7 6 5 4 3 2 1 0
m m R R R
r/m
0 0 0 1 0 0 0 0
unde:
466
Cod
00
01
10
11
Tabelul 6.8.
Registru segment
ES
CS
SS
DS
Apariia codului registru segment determin ca o zon de trei bii s fie completat
0ss, unde ss reprezint codul registrului segment. Dac se impune, codul segment
poate ocupa i poziiile 4, 3 din baitul codului operaie.
Se observ c structura intern a instruciunii reprezint un mod
convenional de punere n coresponden a multitudinii de tipuri de instruciuni cu
coduri. Se urmrete realizarea de combinaii unice, neambigue, iar asamblorul i
dezasamblorul s fie aplicaii, una transformat a celeilalte.
Trecerea la microprocesorul 386 a condus la noi performane. Limbajul de
asamblare a rmas n mare parte nemodificat, iar programatorul poate realiza
construcii noi, putnd integra complet pe cele vechi.
n dinamicile hardware, structura intern a instruciunilor este afectat cel
mai frecvent. n cazul microprocesorului 386 se specific urmtoarele aspecte:
467
codul operaiei ocup doi baii, permind definirea unor noi variante de
prezentare dar i deschiznd posibilitatea definirii de noi instruciuni ca
operaii sau noi tipuri de instruciuni, ca structur de list de operanzi;
lungimile operanzilor sunt un bait, doi baii i patru baii, lucru ce se
reflect prin informaiile descriptorilor d i w;
registrele se codific pentru trei situai: registrele de un bait, registrele
pe 16 bii i registrele EAX, ECX, EDX, EBX, ESP. EBP, ESI, EDI pe
32 de bii, crora li se asociaz coduri tot de trei bii, pe poziiile din
baitul MODRM.
biii r/m iau n considerare toate structurile de expresii de adres n
varianta lucrului pe 16 bii, iar separat n varianta lucrului pe 32 de bii;
factorul de scal pentru adresarea indexat (biii 7, 6) din al treilea bait
de descriere a instruciunii;
registrul index (biii 5, 4, 3) din al treilea bait;
registrul de baz, urmtorii bii, 2, 1, 0;
deplasarea sau constanta imediat se reprezint n continuare pe zero
(dac lipsete) baii, pe un bait, pe doi baii sau pe patru baii;
n cazul instruciunilor de salt condiia de testare este nglobat pe patru
bii n instruciune, primii trei bii definesc combinaia, iar bitul al
patrulea cnd este unu determin complementarea fa de unu a primilor
trei bii.
Trecerea de la un procesor la altul devine pentru programatorul n limbaj de
asamblare un exerciiu de codificare cu amplasarea impus a cmpurilor ntr-o
succesiune dat de bii. Mai apare n plus o completare a listei de instruciuni ca
mnemonice, cu descrieri riguroase i eventual noi resurse (registre) sau noi
caracteristici ale resurselor (lucrul pe 32 de bii).
Prin studierea comparat a structurilor interne ale instruciunilor limbajelor
de asamblare, a frecvenei de utilizare a instruciunilor i a diversitii
instruciunilor i expresiilor de adresare, este posibil proiectare unei codificri
optime, care minimizeaz lungimea textului generat dup asamblare, ca numr de
baii.
6.5 Comentariile
Programele sunt scrise pentru a rezolva probleme dar i pentru a fi
dezvoltate n aa fel nct s continue rezolvarea problemelor, dup un numr de
ani, dup ce au intervenit modificri n algoritmi, prin efectuarea unor modificri n
definirea operanzilor i n secvenele de prelucrare.
Comentariile sunt mai necesare n programele scrise n limbajul de
asamblare pentru caracterul ermetic, codificat al mnemonicelor i al registrelor.
Este preferabil s se introduc numeroase comentarii ca linii surs distincte
dar i n continuarea instruciunilor.
468
Astfel, secvena:
; programul calculeaz suma
; a dou numere a i b
; rezultatul se va afla n c
mov
ax,a
;ax=a
add
ax, b
;ax=ax+b
mov
c,ax
;c=ax
bx, 1fach
bx, x[si] + 0cch
di 1dh, 0ff00h
ax, a
ax, b
ax, 0
alfa
ax, a
ax, b
alfa
469
470
7
DEFINIREA STRUCTURILOR DE DATE
7.1 Date elementare
Datele elementare sunt asociate unor zone de memorie de lungime fixat
care opional sunt iniializate cu constante care impun att natura operanzilor, ct i
setul de instruciuni cu care se va lucra.
Directivele pentru descrierea datelor elementare determin modificarea
contorului cu o unitate dac tipul este DB (Define Byte), cu dou uniti dac tipul
este DW (DefineWord), cu patru uniti pentru tipul DD (Define Double), cu opt
uniti pentru tipul DQ (Define Quad Word) i cu zece uniti pentru tipul DT
(Define Ten).
Secvena:
a
b
c
d
e
f
g
db
dw
dd
dt
dq
dw
db
13
5
0fah
0
7
?
?
:
;
;
;
;
;
;
a
b
c
d
e
f
g
ocup
ocup
ocup
ocup
ocup
ocup
ocup
un bait iniializat cu 13
2 baii iniializai cu 5
4 baii iniializai cu 0fah
10 baii iniializai cu 0
8 baii iniializai cu 7
2 baii neiniializai
un bait neiniializat
471
tip
nume
tip
n
val_j
unde:
n secvena:
x
y
z
w
u
db
dw
dd
db
dw
10 dup (a)
20 dup (0)
40 dup (?)
5
dup (3, 4, 5)
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
tip
dup
(m
dup
(val1-1, val1-2,,val-k))
unde:
nume - identificator cu care se refer matricea;
tip
- descriptor de tip DB, DW, DD, DQ, DT;
n
- numrul de linii ale matricei;
472
m
- numrul de coloane ale matricei;
val-j - valoarea cu care se evalueaz o anumit component.
Operatorul DUP este inclus n mod repetat, permind generalizarea ce
conduce la definirea de masive de masive multidimensionale.
Secvena:
a
b
c
d
e
dw
db
dd
dw
dd
10
3
2
4
4
dup
dup
dup
dup
dup
(10
dup
(3
dup
(7, 4 dup
(1, 2, 3,
(5, 2 dup
(0))
(8), (19))
(3))
4)
(0), 9)
7
7
3
3
3
3
3
3
3
3
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4
5
5
5
5
0
0
0
0
0
0
0
0
9
9
9
9
473
tipul DT-10). De exemplu, masivul bidimensional ee, avnd tipul DD, cu 5 linii i
5 coloane, va ocupa o zon de memorie de 100 baii (4 5 5).
7.4 Articolul
Articolul este un conglomerat de membri, care sunt fie date elementare, fie
masive, fie alte articole. Tipurile membrilor sunt diferite.
Un articol se definete prin:
nume
nume
struc
membrul_1
membrul_2
membrul_n
ends
db
dw
dd
db
dw
30
?
?
?
?
dup
(?)
este definit tipul de date persoana, care este un articol care are n componen ase
membri avnd tipurile DB, DW, DD, DB, respectiv, DW. Lungimea zonei de
memorie ocupat de o variabil de tip STRUC este dat de lungimea membrilor
care intr n alctuirea ei. Astfel, o variabil de tip STRUC persoana va ocupa
30+2+4+1+2=39 baii.
n secvena:
pers persoana (?)
mat_pers persoana 10 dup (10 dup (?))
vect_pr persoana 20 dup (?)
se definesc:
o variabil cu numele de tip STRUC persoana, ce ocup 39 baii, i ai
crei membri se refer cu operatorul . (punct) ca de exemplu, pers.
nume, pers.vrsta, pers.salariu;
474
20 dup (?)
roie
?
(berlina, ,15)
2 dup (break, , 0)
100 dup ( , , 20 )
se definete tipul de dat STRUC maina avnd un cmp cu valoare prefixat (care
poate fi modificat printr-o iniializare ntr-o variabil dac respectiva variabil
impune). Se definete variabila OPEL de tip STRUC maina ale crei cmpuri sunt
iniializate dup cum urmeaz: OPEL.nume = berlina, OPEL.culoare = ROIE,
OPEL.vechime OPEL.vechime=15.
DACIA este un masiv unidimensional cu dou componente de tip STRUC
maina. Prima component are membri iniializai astfel: DACIA.nume = brek,
DACIA.culoare = ROIE, DACIA. vechime=0. A doua component (lungimea
unui articol este 20+5+2=27 baii) are membri referii prin DACIA+27 cu valorile
iniializate urmtoare: DACIA+27.nume=brek, DACIA+27.culoare= ROIE,
DACIA+27.vechime=0.
Masivul unidimensional numit DIVERSE are 100 componente de tip STRUC
maina n care membri culoare i vechime se iniializeaz cu ROIE, respectiv,
valoarea 20.
Articole cu cmpuri definite la nivel de bii
Exist variabile care au un numr de valori restrnse i definirea cu tip DB
nseamn deja risip de memorie. n evidena populaiei, mediul din care provine
persoana este rural sau urban (1 sau 0), sexul individului este masculin sau feminin
(1 sau 0), persoana poate avea sau nu copii (1 sau 0), poate fi necstorit (00),
475
cstorit (01), divorat (10) sau vduv (11). Pregtirea profesional poate fi:
absolvent coal general (001), analfabet (000), absolvent liceu (010), absolvent
coal profesional (011), absolvent postliceal (100 ), liceniat (101), absolvent
colegiu (102), doctor n tiine (110), master in science (111). Persoana poate avea
sau nu carnet de conducere (1 sau 0) poate avea sau nu cazier (1 sau 0). Lucrnd la
nivel de cmpuri de bii cu lungime unu, doi sau trei, se va obine o important
economie de memorie la utilizarea de fiiere pentru colectiviti foarte mari.
Utilizarea de fiiere inverse vine s mreasc viteza de regsire dup combinaii de
caracteristici date sub forma cmpurilor de bii.
Articolele definite cu cmpuri de bii utilizeaz descriptorul RECORD
astfel:
nume record nume-1:n1, nume-2:n2,, nume-k:nk
unde:
nume reprezint numele tipului de dat RECORD ce se definete;
nume-j - numele cmpului j din structura de cmpuri de bii;
nj
- numrul de bii care formeaz cmpul j.
n cazul n care la definire apar construcii de forma:
nume-j:nj=expresie-j
construiete tipul de dat avnd cmpuri pe bii repartizai dup urmeaz: a1 ocup
2 bii, a2 ocup 4 bii, iar a3 ocup 2 bii.
Se creeaz vectorul aa cu trei componente, fiecare component fiind pe un
bait structurat conform tipului de dat RECORD a. Cele trei elemente ale masivului
unidimensional au iniializai biii ce corespund cmpului a2 cu valoarea 0011b.
Dac se lucreaz la nivel de cuvnt este important poziionarea cmpurilor
ntruct baiii rmn uniti de baz i cmpurile nu pot fi dispersate n doi baii
adiaceni. Fiecare asamblor poate impune restricii la lungimea n baii a tipului de
dat RECORD. De cele mai multe ori, lungimea cmpurilor n1+n2++nk nu poate
depi 16 bii.
Cnd se lucreaz cu astfel de structuri se utilizeaz operatorul WIDTH care
returneaz lungimea ca numr de bii a unui cmp cruia i-a fost aplicat.
Dac se construiete secvena:
aaa
record
b:5, c:1, d:2, e:4, f:2, g:2
bbb
aaa
(?)
. . . . . . . .
476
mov
a1, width
bbbb + width
bbb.e
; a1:=000000x00
nume
union
membrul-1
membrul-2
membrul-3
. . . . .
membrul-n
ends
unde:
nume - reprezint un identificator care se asociaz tipului de dat UNION;
membrul-j
- definire tipul de date j;
Lj
- lungimea n baii a variabilei de tipul j.
O variabil de tip UNION nume are o lungime egal cu maximul dintre
lungimile L1, L2, . . ., Ln.
Secvena:
salariu
union
sala dw
5 dup (0)
salb dw
?
nume db
20 dup ?
salariu ends
477
ss
salariu
dup
dw
offset adun
478
dw
dw
dw
dw
offset
offset
offset
offset
scade
produs
rest
ordine
unde: adun, scade, produs, rest i ordine sunt nume de proceduri ce pot fi apelate
prin instruciunea
call
vector_ptr + bx
unde:
nume - tipul de date enum definit de programator;
val_j - valoarea j pe care o poate avea o variabil de acest tip, care se pune
n coresponden cu j 1;
De exemplu, n secvena:
culoare
zile
calificat
boolean
unitate
a
b
c
d
e
s-au definit tipurile de date culoare enum, zile enum, calificat enum, boolean i
unitate tot enum. Variabila a este de tip culoare enum, c este un masiv
unidimensional cu 5 componente de tip califcat enum, variabilele d i e sunt i
iniializate.
Lungimea zonei de memorie asociat depinde de lungimea listei val-j i
poate fi un bait, doi baii, patru baii. De cele mai multe ori codurile sunt 0, 1, 2, . . .
479
enum
pune n eviden c variabila ccc de tip termin ENUM poate lua numai valorile
100, 101 i 102 i 103.
7.7 Tabele de date
Ca n cazul lucrului cu iruri de bii exist posibilitatea de a defini articole
cu cmpuri formate din baii, cuvinte, cuvinte duble, 8 sau 10 baii folosind
descriptorii BYTE, WORD, DWORD, QWORD?. TBYTE SAU PWORD /
FWORD (cmpuri de 6 baii).
Construcia:
nume
TABLE
nume:BYTE:30, salariu:WORD,reineri:WORD:4
480
definete tipul de dat articol TABLE i variabila de tip articol, numit aaa, care
ocup 50 baii. Tipul de date articol TABLE conine masivele unidimensionale
nume i reineri.
7.8 Obiecte
Structura de date obiect este implementat i n limbajele de asamblare.
Aici se vd mai bine implementrile mecanismelor i proprietilor specifice
lucrului cu obiecte.
Un obiect este un conglomerat de membri mult mai neomogen ca structura
de tip articol ntruct accept ca membri proceduri sau pointeri spre proceduri.
nainte de a da regula general de definire a unei structuri de dat obiect, se va
considera exemplul urmtor de definire obiect.
Pentru rezolvarea unei probleme sunt necesare procedurile:
suma procedur NEAR destinat nsumrii elementelor unui vector;
alege procedura FAR destinat alegerii elementului minim dintr-un
masiv bidimensional;
calcul procedur FAR pentru calculul expresiei A/B unde A este suma
returnat de prima procedur, iar B este minimul returnat de procedura
alege.
Datele cu care se vehiculeaz sunt:
vector
matrice
total
minim
raport
dw
dd
dw
dd
dd
100
10
0
?
?
dup
dup
( ? )
( 20 )
struc global
method
ptr_suma:word=suma
ptr_alege:dword=alege
ptr_calcul:dword=calcul
vector
dw
100 dup (?)
matrice
dd
10
dup (20 dup (?))
total
dw
0
minim
dd
?
raport
dd
?
481
calcul_min
ends
482
8
IMPLEMENTAREA STRUCTURILOR
FUNDAMENTALE
8.1 Programarea structurat
Programarea structurat trebuie privit ca o modalitate de disciplinare a
programatorilor i de introducere a unui stil unic n scrierea de texte surs.
Eliminarea instruciunii GO TO din programe este numai aparent deoarece
apelurile de proceduri, instruciunile PERFORM, conin n mod mascat instruciuni
de salt necondiionat n modulele obiect rezultate la compilare.
Limbajele de asamblare conin dezvoltri care implementeaz aproape
perfect cerinele programrii structurate. La nivel de baz implementarea
structurilor fundamentale este o traducere cu posibilitile specifice ale schemelor
asociate acestor structuri.
Obiectivul implementrii structurilor folosind construcii tipizate este de a
obine programe lizibile, cu un nivel de liniaritate mai ridicat i mai simple, chiar
dac lungimea lor ca numr de instruciuni este mare.
8.2 Structura liniar
Structura liniar apare ca o secven de instruciuni ce nu conine salturi
condiionate sau necondiionate, instruciuni de revenire n procedura apelatoare.
Dei instruciunea CALL este nsoit i de un salt necondiionat, ca factor de
liniarizare a programelor se include n mulimea instruciunilor care contribuie la
realizarea de structuri liniare.
Structura liniar conine instruciuni care se execut una dup cealalt,
exact n ordinea n care apar n secven.
Secvena:
mov
add
add
sub
mul
mov
ax,0
ax, b
ax, c
ax, d
ax, e
prod, ax
;
;
;
;
;
ax:=ax+b
ax:=ax+c
ax:=ax-d
dx:ax:=ax e
prod:=ax
483
mov
prod+2,dx ; prod+2:=dx
Secvena:
mov
cmp
jg
ax, a
ax, b
adevrat
mov
maxim, b
fals:
484
jmp
adevrat :
mov
final:
nop
final
maxim, ax
ax, a
ax, b
fals
maxim, ax
final
maxim, b
n cazul n care n program se cere implementarea structurii pseudoalternative IF THEN, este preferabil s se modifice de la nceput testul
indicatorilor de condiie pentru a obine o construcie natural, fr instruciuni de
salt necondiionat introduse n plus.
Secvena:
cmp
jge
mov
mov
int
final:
mov
int
ax,0
final
ah, 9
dx, OFFSET text
21h
;afiare text
ah, 4ch
21h
485
cmp
jl
jmp
negativ:
mov
mov
int
final:
mov
int
ax, 0
negativ
final
ah, 9
dx, OFFSET text
21h
ah, 4ch
21h
care are dou instruciuni de salt consecutive, greu de acceptat n programe scrise
n limbaj de asamblare eficiente.
Compunerea structurilor alternative impune realizarea unei liniarizri a
secvenelor fr a introduce multe instruciuni de salt.
Secvenei:
IF (condiie_1) THEN
IF (condiie_2) THEN
secvena_1
ELSE
secvena_2
ELSE
IF (condiie_3) THEN
secvena_3
ELSE
secvena_4;
486
nop
final_2:
nop
final_3:
nop
secvena
de repetat
cx:=cx-1
nu
cx=0
da
Figura 8.1- Structur repetitiv condiionat posterior
487
si,
di,
ax,
cx,
si
di
ax
15
ax, x [si]
si, 2
ciclu
suma, ax
bx, bx
cx, NR_LINII
xor
xor
push
mov
ax, ax
si, si
cx
ax, NR_COL
ciclul1:
ciclul2:
add
add
loop
mov
add
add
pop
loop
488
iniializri
expresia
condiie
secvena de
repetat
modificare
operanzi din
expresia
condiie
ax, 0
si, 0
cx, 0
489
ciclu:
cmp
jg
cmp
je
add
add
inc
jmp
final:
mov
mov
ax, 1000
final
cx, n
final
ax, x[si]
si, 2
cx
ciclu
suma, ax
numr, cx
cele dou teste conduc spre instruciunea cu eticheta final, iar asigurarea repetrii
este dat de instruciunea jmp ciclu. Controlul numrului de repetri se asigur
att prin contorul CX ct i prin valoarea registrului AX. Dac testul este efectuat
asupra registrului CX i n secvena repetitiv nu se modific n mod corespunztor
(dac se pornete de la zero are loc incrementarea, iar dac se pornete de la limita
superioar a intervalului are loc decrementarea) efectul este ciclarea infinit.
n toate cazurile se urmrete stabilirea corect a numrului de repetri.
Testarea incorect a limitei intervalului va conduce fie la neincluderea n calcule a
unor elemente (primul element dac se va ncepe cu limita interioar unu), fie la
includerea unui element din afara intervalului (dac se ncepe cu elementul zero i
se numr n elemente n loc de n-1).
8.5 Structura repetitiv condiionat posterior
Forma nestandard este utilizat cnd numrul de repetri e dependent de
valoarea unei expresii sau de semnul acesteia sau cnd variabila de control
genereaz termenii unei progresii, alta dect progresia aritmetic cu primul termen
n, al doilea termen n-1, iar ultimii termeni nu sunt 3,2,1,0.
Se utilizeaz condiionarea posterioar pentru a nu mai repeta unele
instruciuni. De exemplu, pentru afiarea unor texte introduse de la terminal se
procedeaz astfel:
se afieaz mesajul: INTRODUCEI TEXTUL:;
se introduce textul de ctre utilizator;
se afieaz mesajul: DORII S CONTINUAI? (d/n);
se tasteaz d sau n i dialogul continu sau e terminat.
Dac se utilizeaz structura repetitiv condiionat anterior este necesar ca
nainte de testul de continuare, n mod artificial s se iniializeze variabila
RSPUNS (definit RSPUNS EQU al) cu constanta n. Structura repetitiv
condiionat posterior evit acest impediment, aa cum se poate vedea n secvena:
ciclu:
mov
ah,9
490
mov
int
mov
mov
int
mov
mov
int
mov
int
cmp
jz
cmp
jz
mov
int
dx, OFFSET
21h
ah, 0ah
dx, OFFSET
21h
ah,9
dx, OFFSET
21h
ah,1
21h
a1,d
ciclu
a1, D
ciclu
ah, 4Ch
21h
textl ;text
;text
invitaie
ir caractere
text2 ;text
introdus
text3 ;text
de continuare
;funcia de
;introducere caractere:
cmp
var, VALI
etich_1
var, VAL2
etich_2
var, VAL_n
491
jz
etich_n
etich_0:
secvena_0
jmp
etich_m
etich_1
secvena_1
jmp
etich_m
etich_n:
etiche
secvena_n
etich_m:
nop
a b
a b
a * b
e
b 1
a 1
daca x 1
daca x 2
daca x 3
daca x 4
daca x 5
in celelalte cazuri
x,1
aduna
x,2
scade
x, 3
produs
x, 4
decrement
x,5
increment
mov
jmp
e, 0
final
zero:
aduna:
492
mov
add
mov
jmp
ax, a
ax, b
e, ax
final
mov
sub
mov
jmp
ax, a
ax, b
e, ax
final
mov
mov
mul
mov
jmp
ax, a
bx, b
bx
e, ax
final
mov
dec
mov
ax, a
ax
e, ax
scade:
produs:
decrement:
final:
nop
x, 1
salt_1
mov
add
jmp
ax, a
ax, b
final
cmp
jne
ax, 2
salt_2
mov
sub
jmp
ax, a
ax, b
final
cmp
jne
x, 3
salt_3
mov
mul
jmp
ax, a
b1
final
adun:
salt_1:
scade:
salt_2:
produs:
salt_3:
493
cmp
jne
x, 4
salt_4
mov
dec
jmp
ax, b
ax
final
cmp
jne
x ,5
salt_5
mov
inc
jmp
ax, a
ax
final
mov
ax, 0
mov
e, ax
decrement:
salt_4:
increment:
salt_5:
final:
9
ARITMETICI BINARE
9.1 Aritmetica binar pe 8 bii
Aritmetica pe 8 bii presupune definirea operanzilor surs ai expresiilor cu
descriptorul DB.
Pentru efectuarea adunrii se utilizeaz instruciunea add. De exemplu,
pentru evaluarea expresiei:
e = a + b
se utilizeaz secvena:
494
a
b
e
db
db
db
mov
add
mov
al, a
al, b
e, al
20
13
?
Regitrii care particip la aritmetica pe 8 bii sunt AH, AL, BH, BL, CH, CL, DH
i DL.
Iniializarea cu zero a unui registru se efectueaz prin instruciuni precum:
mov
sub
ah, 0
bl, bl
xor
mov
cl, cl
ch, cl
db
db
db
25
7
?
mov
mov
sub
mov
ch, x
dl, y
ch, dl
z, ch
evalueaz expresia:
z=x-y
nmulirea pe 8 bii utilizeaz instruciunea mul. Denmulitul se
memoreaz n registrul AL, iar rezultatul se va gsi n registrul AH : AL.
Secvena:
a
b
c
e
f
g
db
db
db
dw
dw
dw
mov
mov
mul
al, a
bl, b
bl
7
5
8
?
?
?
495
mov
mov
mul
mov
mov
mul
mov
e, ax
al, a
c
f, ax
al, a
3
g, ax
evalueaz expresiile :
e = a * b
f = a * c
g = 3 * a
db
db
db
db
mov
cbw
div
mov
mov
al, a
32
4
?
?
b
cat, ah
rest, al
evalueaz expresia:
cat = [a/b]
rest = a cat * b
496
fie ca registru:
div cl
sau
div dh
sau
div bl
sau
div 2
dw
dw
dw
mov
add
mov
ax, a
ax, b
e, ax
20
13
?
ax, 0
sub
bx, bx
497
xor
cx, cx
dw
dw
dw
25
7
?
mov
mov
sub
mov
cx, x
dx, y
cx, dx
z, cx
evalueaz expresia:
z = x-y
nmulirea pe 16 bii utilizeaz instruciunea mul. In timp ce denmulitul se
memoreaz n registrul AX, rezultatul se va gsi n perechea de regitrii DX:AX.
Secvena urmtoare:
a
b
c
e
f
g
dw
dw
dw
dd
dd
dd
mov
mov
mul
mov
mov
mov
mul
mov
mov
mov
mul
mov
mov
ax, a
bx, b
bx
e, ax
e+2, dx
ax, a
c
f, ax
f+2, dx
ax, a
3
g, ax
g+2, dx
evalueaz expresiile :
e = a * b
f = a * c
g = 3 * a
7
5
8
?
?
?
498
dw
dw
dw
dw
mov
cwd
div
mov
mov
ax, a
32
4
?
?
b
cat, ax
rest, dx
evalueaz expresia:
cat = [a/b]
rest = a cat * b
fie ca registru:
div cx
sau
div bx
sau
div 2
499
A92Fh
49837h
?
ax, dp1
ax, dp2
dpsum, ax
ax, dp1+2
ax, dp2+2
dpsum+2, ax
evalueaz expresia:
dpsum = dp1 + dp2
0 0 0 6 A 9 2 F +
0 0 0 4 9 8 3 7
0 0 0 B 4 1 6 6
sau detaliat:
carry 1+
0 0 0 6+
0004
A92F+
9837
000B
4166
dd
dd
dd
6A92Fh
4B837h
?
mov
sub
mov
ax, b
ax, a
bx, b+2
500
sbb
mov
mov
bx, a+2
c, ax
c+2, bx
evalueaz expresia:
c = a - b
0006A92F0004B837
0001F0F8
sau detaliat:
0 0 0 60 0 0 4carry 1
A92FB837
0001
F0F8
dd
dd
dd
dd
<valoare oarecare>
<valoare oarecare>
<valoare oarecare>
?
mov
mov
add
adc
add
adc
sbb
sbb
mov
mov
ax, x
dx, x+2
ax, y
dx, y+2
ax, 24
dx, 0
ax, z
dx, z+2
w, ax
w+2, dx
501
32
a1 b2 216 + a2 b2 +
+ a2 b1 216
ax, a
b
rez, ax
cx, dx
ax, a + 2
b
bx, dx
cx, ax
bx, 0
ax, a
b + 2
cx, ax
bx, dx
rez + 2, cx
cx, 0
cx, 0
ax, a + 2
b + 2
ax, bx
dx, cx
rez + 4, ax
rez + 6, dx
502
S=B
C=0
ct timp ( S <= A )
{
C=C+1
S=S+B
}
R=A(SB)
Aceast metod este relativ rapid, deoarece nu folosete dect operaii de
adunare i de scdere pe 32 de bii. n limbaj de asamblare, transpunerea
pseudocodului de mai sus arat astfel:
a
dd
<valoare>
b
dd
<valoare>
c
dd
?
r
dd
?
s
dd
?
. . . . . . . . .
mov
ax, offset s
mov
word ptr [ax], b
mov
word ptr [ax+2], b+2
mov
ax, offset c
mov
word ptr [ax], 0
mov
word ptr [ax+2], 1
iar:
cmp32
jg
add32
add32
jmp
s, a
et
c, 1
s, b
iar
sub32
mov
mov
mov
sub32
s, b
ax, offset r
word ptr [ax], a
word ptr [ax+2], a+2
r, s
et:
503
mov
cmp
iesire:
ax, val + 2
ax, val2 + 2
ENDM
Se compar mai nti prile mai semnificative ale celor dou valori. Numai
dac acestea sunt egale se trece la compararea parilor mai puin semnificative. n
final indicatorii de condiie vor fi setai corespunztor.
Aceste structuri de cod pot fi folosite atunci cnd nu se poate face uz de un
coprocesor matematic, iar microprocesorul nu posed regitri pe mai mult de 16
bii. Odat cu apariia microprocesoarelor pe 32 de bii, se pot folosi registrele
generale EAX, EBX, ECX, EDX. Aceste metode nc prezint importan pentru
operaii cu numere de peste 64 de bii, ele putnd fi extinse foarte uor pe orice
numr de bii, atunci cnd se lucreaz cu numere foarte mari.
10
ARITMETICI ZECIMALE
10.1 Ajustri
Aritmetica zecimal presupune efectuarea operaiilor bait cu bait n cazul
reprezentrii despachetate sau nibble cu nibble pentru reprezentarea mpachetat.
Pentru a menine la nivelul fiecrui bait reprezentri ale cifrelor de la 0 la 9
se impune efectuarea de ajustri care se fac n mod diferit n funcie de operaiile
efectuate asupra operanzilor.
De exemplu, ajustarea pentru adunarea zecimal despachetat nseamn
corectarea fiecrui nibble mai puin semnificativ a fiecrui octet n cazul unei
depiri la adunare. Rezultatul adunrii numerelor:
0
0
0
1
6
7
0
0
0
3
6
9
0
0
0
5
1
6
0
0
0
8
0
8
504
0
0
8
F
0
0
7
C
0
0
9
F
3
7
A
7
8
F
8
5
D
5
8
D
4
7
B
505
{
(AL)(AL)-6
(AH)(AH)-1
(AF)1
(CF)(AF)
(AL)(AL) & 0Fh
}
Pentru reprezentri ale numerelor n format zecimal mpachetat:
DAA (Decimal Adjust for Addition): ajustare pentru adunare: dac cel mai
puin semnificativ nibble al registrului AL este mai mare dect 9 sau dac AF este
setat pe 1, atunci la registrul AL se adun 6 si AF este setat pe 1. Dac AL este mai
mare dect 9Fh sau dac AF este setat pe 1, atunci la registrul AL se adun 60h i
AF este setat pe 1.
DAS (Decimal Adjust for Subtraction): ajustare pentru scdere: dac cel
mai puin semnificativ nibble al registrului AL este mai mare dect 9 sau dac AF
este setat pe 1, atunci din registrul AL se scade 6 si AF este setat pe 1. Dac AL
este mai mare dect 9Fh sau dac AF este setat pe 1, atunci din registrul AL se
scade 60h i AF este setat pe 1.
10.2 Adunarea i scderea
ADD - Arithmetic Addition (Adunare)
Operatori
reg,reg
mem,reg
reg,mem
reg,immed
mem,immed
accum,immed
Timpi
808x 286
3
2
16+EA 7
9+EA 7
4
3
17+EA 7
4
3
De exemplu, secvena:
termen1
termen2
dw
dw
11
23
386
2
7
6
2
7
2
486
1
3
2
1
3
1
rezultatul n
Lungime
Bytes
2
2-4 (W88=24+EA)
2-4 (W88=13+EA)
3-4
3-6 (W88=23+EA)
2-3
506
total
dw
..
mov ax, termen1
add ax, termen2
mov total, ax
386
2
6
7
2
7
2
486
1
3
2
1
3
1
Lungime
Bytes
2
2-4 (W88=24+EA)
2-4 (W88=13+EA)
3-4
3-6 (W88=25+EA)
2-3
Astfel, secvena:
termen1
dw
termen2
dw
dif
dw
7
15
?
507
Operatori
reg8
reg16
reg32
mem8
mem16
mem32
Timpi
808x
286 386
70-77
13
9-14
118-113
21
9-22
9-38
(76-83)+EA 16
12-17
(124-139)+EA 24
-
486
13-18
13-26
13-42
13-18
12-25
12-21
Lungime
Bytes
2
2
2-4
2-4
13-26 2-4
13-42 2-4
Astfel, secvena:
factor1
dw
factor2
dw
produs
dd ?
..
mov ax, factor1
mul ax, factor2
mov produs, ax
mov produs+2, dx
41
15
508
509
Tabelul 10.1.
-128127
0255
-3276832767
065535
-2^312^31-1
02^32-1
1 octet cu semn
1 octet fr semn
2 octei cu semn
2 octei fr semn
4 octei cu semn
4 octei fr semn
32
34
35
38
39
33
31
30
36
x
Figura 10.1 Imaginea zonei de memorie ocupat de irul x
folosind codurile ASCII pentru simbolurile cifrice.
Dac se traverseaz masivul unidimensional x (de la stnga la dreapta) i
din fiecare bait se scade constanta 30h (care corespunde caracterului 0) se va
obine irul x modificat a crui imagine este:
07
02
04
05
08
09
03
01
00
06
510
45
89
31
06
y
Figura 10.3 Imaginea zonei de memorie ocupat de variabila y
mpachetarea se face de la dreapta la stnga i dac numrul de cifre este
impar se completeaz baitul cel mai din stnga n partea mai semnificativ cu bii
de 0. Astfel numrul 72541 introdus de la tastatur va ocupa o zon de memorie a
cu coninutul:
37
32
35
34
31
a
Figura 10.4 Imaginea zonei de memorie ocupat de variabila a
Transformarea sa n numr zecimal despachetat n zona de memorie b este:
07
02
05
04
01
b
Figura 10.5 Imaginea zonei de memorie ocupat de variabila b
mpachetarea numrului coninut de zona de memorie b n zona de memorie
c este:
07
25
41
c
Figura 10.6 Imaginea zonei de memorie ocupat de variabila c
n continuare sunt prezentate exemple de proceduri pentru operaii n
aritmetica zecimal:
.data
buf db 255,255 dup(?)
null equ 0ffh
511
.code
; procedura de citire de la tastatur a unui ir de caractere
cifrice :
; adresa destinaiei este es:[di]
getnumber proc
cld
mov ah, 0ah
mov dx, seg buf
mov ds, dx
mov dx, offset buf
mov [dx], 255
int 21h
mov si, offset buf
inc si
xor cx, cx
mov cl, byte ptr [si]
inc si
@@01:
lodsb
cmp al, 0
jb @@02
cmp al, 9
ja @@02
stosb
loop @@01
@@02:
mov byte ptr [di], null
ret
getnumber endp
; procedura de aflare a numrului de octei
; adresa irului n es:[di] i rezultat n ax
ndigit proc
cld
mov bx, di
mov al, null
xor cx, cx
not cx
repne scasb
mov ax, di
sub ax, bx
dec ax
ret
ndigit endp
; procedura de conversie ir de cifre zecimal despachetat
; sursa ds:[si], destinaia es:[di]
asctobcd proc
cld
mov ah, null
@@03:
lodsb
512
cmp al, ah
je @@04
sub al, 0
stosb
jmp @@03
@@04:
stosb
ret
asctobcd endp
; procedura de conversie zecimal despachetat ir de cifre
; sursa ds:[si], destinaia es:[di]
bcdtoasc proc
cld
mov ah, null
@@05:
lodsb
cmp al, ah
je @@06
add al, 0
stosb
jmp @@05
@@06:
stosb
ret
bcdtoasc endp
; procedura de conversie despachetat mpachetat
; sursa ds:[si], destinaia es:[di]
unpackedtopacked proc
cld
push es
push di
mov di, si
mov ax, ds
mov es, ax
call ndigit
mov cx, ax
pop di
pop es
shr cx, 1
jnc @@07
movsb
@@07:
lodsw
shl ah, 1
shl ah, 1
shl ah, 1
shl ah, 1
or al, ah
stosb
loop @@07
513
movsb
ret
unpackedtopacked endp
; procedura de conversie mpachetat despachetat
; sursa ds:[si], destinaia es:[di]
packedtounpacked proc
cld
@@07:
lodsb
cmp ah, null
je @@08
mov ah, al
shr ah, 1
shr ah, 1
shr ah, 1
shr ah, 1
and al, 0fh
stosw
jmp @@07
@@08:
stosb
ret
packedtounpacked endp
; procedura de copiere a unui ir terminat cu caracterul
special (null)
; sursa ds:[si], destinaia es:[di]
bcdcopy proc
cld
@@09:
mov ah, null
lodsb
cmp al, ah
stosb
je @@09
bcdcopy endp
; procedura de redimensionare a unui numr zecimal mpachetat
; sursa ds:[si], destinaia es:[di], dimensiune ir nou n
ax
bcdnorm proc
cld
push ax
push es
push di
mov ax, ds
mov es, ds
mov di, si
mov al, null
xor cx, cx
neg cx
514
repne scasb
mov cx, di
sub cx, si
mov si, di
dec si
pop di
pop es
pop ax
add di, ax
sub ax, cx
std
rep movsb
mov cx, ax
mov al, 0
rep stosb
ret
bcdnorm endp
; procedura de adunare zecimal mpachetat
; sursa ds:[si], destinaia es:[di] (dest=dest+sursa)
; considerm numerele normalizate la un numr dat de octei
dat ;n cx
bcdadd proc
cld
clc
@@10:
lodsb
adc al, byte ptr es:[di]
daa
stosb
loop @@10
ret
bcdadd endp
; procedura de scdere zecimal mpachetat
; sursa ds:[si], destinaia es:[di] (dest=destsursa)
; considerm numerele normalizate la un numr dat de octei
dat n cx
bcdsub proc
cld
clc
@@11:
lodsb
abb al, byte ptr es:[di]
das
stosb
loop @@11
ret
bcdsub endp
; exemplu de apelare proceduri
.data
515
s1 db 12632, null
; ascii
s11 db 11 dup(?)
; unpacked bcd
s12 db 11 dup(?)
; packed bcd
s13 db 11 dup(?)
; normalized packed bcd
s2 db 0, 0, 0, 0, 0, 0, 0, 22, 31, 69
; normalized
packed bcd
.code
start:
mov ax, seg s1
mov es, ax
mov ds, ax
lea si, s1
lea di, s11
call asctobcd
lea si, s11
lea di, s12
call unpackedtopacked
lea si, s12
lea di, s13
mov ax, 10
call bcdnorm
lea di, s13
lea si, s2
mov ax, 10
call bcdadd
end
516
11
NTRERUPERI
11.1 ntreruperi interne i externe
O ntrerupere este un eveniment care duce la ntreruperea temporar a
execuiei unui program, executnd o subrutina numit serviciul ntreruperii
(Interrupt Service Routine ISR), dup care reia programul oprit din acelai punct,
ca i cnd nu s-ar fi ntmplat nimic. ntreruperile au fost realizate ca alternativ la
examinarea repetat a perifericelor pentru detectarea unei operaii de intrare/ieire
(polling). Astfel, n locul acestei interogri repetate i costisitoare, perifericele
genereaz semnale de ntrerupere, apelnd serviciul corespunztor.
Dei momentul de declanare este oarecare, semnalele de ntrerupere nu
sunt recunoscute de ctre procesor dect ntre doua apeluri de instruciuni. Astfel,
dac se execut o instruciune ce necesit multe cicluri maina (cum este, spre
exemplu, o nmulire, care poate necesita pn la 139 de cicluri procesor), iar un
apel de ntrerupere are loc n timpul acesta, el este pus n ateptare pn la
terminarea instruciunii. Excepie de la aceast regula o fac instruciunile cu
repetare, cum sunt instruciunile de lucru cu iruri (de exemplu rep movsb), care
sunt ntrerupte.
n cadrul programrii procesoarelor din familia 8086, ntreruperile se mpart
n dou clase:
ntreruperi externe
ntreruperi interne
ntreruperile externe au loc n momentul generrii unui semnal de ctre
diferitele dispozitive spre procesor. Pe de alt parte, ntreruperile interne sunt
declanate n dou moduri: ca urmare a apelului unei instruciuni int sau ca urmare
a unei excepii generate de o condiie de eroare (cum ar fi spre exemplu mprirea
la zero). ntreruperile interne generate prin apeluri int se mai numesc ntreruperi
software.
11.2 Modul de funcionare a ntreruperilor
Un serviciu oferit de o ntrerupere nu este altceva dect un tip special de
subprogram. Subprogramele implicite pot fi nlocuite cu rutine construite de ctre
programator. Datorit faptului c aceste servicii nu sunt proceduri obinuite, cteva
msuri trebuiesc luate n cadrul lor:
517
518
Nivelul PIC
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
NMI
Numarul Intreruperi
08h
09h
0Ah
0Bh
0Ch
0Dh
0Eh
0Fh
070h
071h
072h
073h
074h
075h
076h
077h
02h
Tabel 11.1.
Dispozitiv
Timer (ceasul software)
Tastatura
Slave 8259
Portul serial secundar (COM2)
Protul serial primar (COM1)
Hard Disk (Fix)
Floppy Disk
Imprimanta pe port paralel
Ceasul hardware
Master 8259 Nivel 2
Coprocesorul numeric
Hard Disk (Fix)
Paritate Memorie
519
520
Acest exemplu poziioneaz cursorul pe linia 10, coloana 12, pe prima pagina
video, apelnd funcia 02h a serviciului 10h. Modul de folosire al ntreruperilor
521
Tabel 11.2
Numr ntrerupere
00h
01h
02h
03h
04h
05h
06h
07h
08h
09h
0Ah
0Bh
.....
10h
11h
12h
13h
14h
.....
40h
41h
43h
46h
4ah
67h
70h
.....
76h
77h
Semnificaie (serviciu)
Divizare la zero
Modul single-step (vezi flag tf)
Nemascabil (NMI)
Breakpoint
Depsire (overflow) (vezi flaguri of si ov)
Tiprire ecran
Cod de operaie nevalid
Nu exist coprocesor matematic
IRQ0 Timer
IRQ1 Tastatur
IRQ2 cascade (trecerea pe controllerul 2 de
ntreruperi)
IRQ3 COM 2/4
.....
Serviciul video
Lista echipamentelor
Mrimea memoriei convenionale
Disk I/O
Port serial
.....
Vector ctre funciile int 13h referitoare la
dischet
Vectori ctre structurile referitoare la hard
discuri
Tabela de caractere EGA si VGA
Vectori ctre structurile referitoare la hard
discuri
Alarm utilizator
Funcii ale managerului de memorie expandat
IRQ8 Real Time Clock
.....
IRQ14 hard disk
IRQ15 (rezervat)
522
Semnificaie (serviciu)
Terminare program
Servicii DOS
Adresa de revenire din program dup terminarea
acestuia
Adresa de revenire dup terminare cu Control-Break
Adresa de revenire dup o eroare critic
Acces direct la disc
Terminare program cu rmnere rezindent n memorie
Procesor neocupat (idle)
Acces rapid la ecran
Executare comand DOS
Multiserviciu (DoubleSpace, spooler, control TSR, etc.)
Servicii DPMI (folosite sub modul Windows 386Enh)
Suport mouse
Servicii ale managerului de memorie expandat
(HIMEM.SYS)
ah, 09h
dx, sir
21h
523
524
registru
de date
es = ds
; stabilire pauza
;salvare registru es
;obtinerea vectorului de
; apel serviciu DOS
; salvare segment
525
mov [timerOfs], bx
; salvare offset
pop es
; restaurare es
push ds
; salvare registru ds
mov ax, 251Ch
; setarea serviciului 1C
push cs
; ds = cs
pop ds
mov dx, offset Incetinire ; adresa de inlocuire
int 21h
; setare adresa
pop ds
; restaurare ds
@@10:
call KeyWaiting
jz @@10
push ds
mov ax, 251Ch
mov dx, [timerOfs]
initiala
mov ds, [timerSeg]
int 21h
pop ds
Exit:
mov ah, 04Ch
mov al, [codIesire]
int 21h
;****************************************
; Incetinire - Procedura apelata de aprox. 18,2/sec
; ****************************************
inProgress DB
0
; flag
difference DW
0
; timpul de incetinire
PROC
Incetinire
;
;
;
;
push ds
push dx
mov al, EOI
out PIC8259, al
; al = end-of-interrupt
526
mov
mov
mov
@@10:
mov
ax, BIOSData
ds, ax
ax, [word LowTimer]
; incarcare valoare
; timer in dx
; scadere valoare
; noua - veche
; comparare cu
; pauza
; cicleaza pana la
; depasire
; dezactivare intreruperi
; in timpul restaurarii
; flag pe zero
sub dx, ax
cmp dx, [cs:difference]
jb @@10
cli
KeyWaiting
push ax
mov ah, 1
int 16h
pop ax
ret
ENDP
KeyWaiting
END
Start
;
;
;
;
;
;
;
salvare ax
functia de
verificare buffer
serviciu tastatura
BIOS
restaurare ax
retur
; sfarsit program
527
ds
ax, @data
ds, ax
. .
DB
DW
0
0
; flag
; timpul de incetinire
[byte cs:inProgress], 0
528
partea timerului n timpul execuiei procedurii Incetinire, dac aceasta dureaz prea
mult. Astfel, acest rutin devine reentrant. Din pcate scrierea unei funcii
reentrante ridic probleme sulpimentare, chiar rutinele din cadrul BIOS-ului si
DOS-ului nefiind reentrante. Posibilitatea reapelrii procedurii Incetinire poate s
duc la depirea stivei dac procedura dureaz prea mult, iar lanul de reapelrii
continu fr oprire. Mai mult, folosirea unor variabile globale face ca execuia s
ia o ntorstur neprevzut, o singur instan a acestora fiind folosit la toate
apelurile. Dup cum se observ folosirea variabilei difference, face imposibil
folosirea rutinei Incetinire n mod reentrant. Soluia la aceast problem (soluie pe
care o folosesc i unele funcii BIOS/DOS, cum ar fi Print Screen) este folosirea
unui flag (n cazul de mai sus inProgress), care s indice dac o instan a rutinei
este deja apelat:
cmp
[byte cs:inProgress], 0
Dac inProgress este mai mare ca zero, instana curent a aprut ca urmare
a blocrii altui apel al rutinei, i se sare la sfritul procedurii. Dac este zero,
instana curent este singura apelat n acest moment i se poate continua execuia
ei. Urmeaz incrementarea flagului pentru indicarea acestui lucru.
Dup luarea acestor msuri, urmeaz altele: permiterea altor ntreruperi (sti)
i salvarea regitrilor folosii n stiv. Dei, la prima vedere, instruciunea sti pare
suficient pentru activarea ntreruperilor, datorit faptului c ntreruperile timerului
sosesc prin intermediul cipului 8259, acest lucru nu este adevrat. Dei
instruciunea sti seteaz flagul if, permind indicarea ctre procesor a semnalelor
de ntrerupere, primirea de ctre acesta a ntreruperilor necesit trimiterea ctre
portul 8259 (cu valoarea 20h) a unei comenzi end-of-interrupt (EOI):
PIC8259
EOI
EQU
EQU
. . . .
mov
out
. . . .
529
ntreruperile nu pot opri execuia codului ntre instruciunile mov ss, ax i mov
sp, offset sfarsitStiva. Dac acest lucru nu s-ar realiza n mod automat, iar o
ntrerupere ar avea loc chiar ntre cele doua instruciuni, codul de tratare apelat va
folosi vechea valoare a deplasamentului mpreun cu noua valoare a segmentului
de stiva, o situaie cu urmri catastrofale. Prin urmare, pentru folosirea acestei
metode de protecie, orice modificare a unui segment, trebuie urmat de
actualizarea deplasamentului.
Pentru o rutin de tratare a unei ntreruperi, declararea unui segment de
stiv local de 512 baii face astfel:
ALIGN
stivaLocala DB
sfarsitStiva
unde directiva ALIGN este necesar pentru alinierea stivei la un multiplu de cuvnt
procesor. Se declar, apoi, o serie de variabile pentru reinerea vechilor regitri:
ssVechi
spVechi
axVechi
DW
DW
DW
0
0
0
[cs:ssVechi], ss
[cs:spVechi], ss
[cs:axVechi], ax
530
mov
mov
mov
ax, cs
ss, ax
sp, offset sfarsitStiva
ss, [cs:ssVechi]
sp, [cs:spVechi]
ax, [cs:axVechi]
Dup cum se observ, o sarcin aparent simpl, cum este cea de folosire a
timer-ului, necesit cunoaterea profund a implicaiilor pe care le implic
utilizarea ntreruperilor, nerespectarea regulilor mai sus amintite ducnd inevitabil
la terminarea anormal a programului sau, chiar, la o cdere de sistem.
11. 5 Concluzii
Folosirea ntreruperilor nu este o sarcin uoar. De multe ori soluia cea
mai simpl este folosirea unui limbaj de nivel nalt. Dar, de i mai multe ori, ceea
ce ofer aceste limbaje, referitor la folosirea direct a hardware-ului, nu este de
ajuns. Prin urmare, folosirea limbajului de asamblare i a ntreruperilor devine
inevitabil. Sistemele de operare noi (Windows NT, Windows 2000) nu permit
accesarea direct de hardware, oferind soluii de nivel nalt pentru accesarea
acestuia. Totui, scrierea de programe specifice i dedicate unor sarcini precis
determinate, cum este scrierea unor drivere, accesarea unor echipamente noi,
necesit realizarea unui cod care s ruleze n mod nucleu i care s acceseze
resursele direct. Astfel, programarea cu ntreruperi i pstreaz actualitatea.
531
12
MACRODEFINIII
12.1 Structura macrodefiniiei
Macrodefiniia este o secven de program scris n limbaj de asamblare care
corespunde unei prelucrri cu caracter repetat.
Se construiesc macrodefiniii pentru prelucrri precum:
mprirea a dou numere cu obinerea ctului i restului precum i a
unei informaii asupra modului n care s-a efectuat mprirea (de
exemplu mpritor zero);
preluarea unui caracter sau a unui ir de la tastatur;
afiarea unui caracter sau a unui ir pe ecranul monitorului;
diverse operaii de formatare a ecranului, ca de exemplu tergerea
ecranului, poziionarea cursorului;
operaii cu fiiere: deschiderea, crearea, citirea, tergerea, nchiderea
fiierelor, poziionarea cursorului;
aflarea minimului sau maximului dintre elementele unui vector sau a
unei matrice.
Pentru a construi o macrodefiniie se impune:
definirea datelor de intrare;
specificarea schemei logice de prelucrare a datelor de intrare;
definirea rezultatelor.
Se constituie lista de parametri finali format din:
parametrii care corespund datelor de intrare;
parametrii n care se vor gsi rezultatele;
parametrii n care se regsesc informaii privind modul n care s-au
efectuat prelucrrile.
Macrodefiniia pentru adunarea a dou matrice conine lista de parametrii
formali format din:
numele primei matrice (de fapt adresa zonei unde este memorat
matricea);
numele celei de-a dou matrice;
numrul de linii al matricelor;
numrul de coloane;
numele matricei de rezultat;
532
variabila boolean care are valoarea zero Dac prelucrarea s-a efectuat
corect, respectiv unu n caz contrar.
Parametrii p1, p2, .. pn sunt descrii n prima linie surs a macrodefiniiei,
n care se mai specifica numele macrodefiniiei, cuvntul cheie MACRO, linie cu
structura:
nume_macrodefinitie
macro
macro
a, b, s, stare
macro
533
mov s,
pop ax
endm
ax
referirea
unde:
nume_macro numele macrodefiniiei
pfi parametrul formal i
pri parametrul real i
Dac se consider macrodefiniia aduna, definit anterior n subcapitolul
12.1 i expresia:
e = a + b + c + d
se fac macroapelurile:
aduna a, b, e
aduna e, c, e
aduna e, d, e
534
endm
1
3
7
13
2
32
a, b, c, rez1
x, y, z, rez2
0, rez1, rez2, e
535
Textul surs obinut este mai lung avnd un numr de instruciuni mai mare
dect textul iniial. Dac programul asamblor este nzestrat cu componente de
optimizare, atunci se obine eliminarea din programul macroexpandat a secvenelor
de instruciuni
pop ax
push ax
macro a, b, c, min
local et1, et2
push ax
mov ax, a
cmp ax, b
jlz et1
mov ax, b
et1:
cmp ax, c
jlz et2
mov ax, c
et2:
mov min, ax
pop ax
endm
Programul principal:
536
...
minim
minim
minim
minim
...
x, y,
w, v,
i, j,
min1,
z, min1
u, min2
k, min3
min2, min3, min
537
jlz et10003
mov ax, min2
et10003:
cmp ax, min3
jlz et20003
mov ax, min3
et20003:
mov min, ax
pop ax
...
Cele patru cifre ataate etichetei locale limiteaz macroapelurile la cel mult
10000 ntr-un program.
12.4 Variabile locale
Variabilele locale sunt variabile care sunt cunoscute doar n blocul n care
au fost definite. Se pune problema zonelor de memorie, n care s fie alocate aceste
variabile locale:
segmentul de date global
segmentul de date propriu
stiva
n primul caz se profit de faptul c directivele simplificate de definire a
datelor (.date) i a codului (.code) pot alterna n cadrul programului. Variabilele
locale sunt mai nti definite cu directiva LOCAL, pentru a nu fi duplicate n apeluri
succesive, apoi declarate n cadrul segmentului de date .data.
Astfel se definete o constant local, care poate fi aplicat diferitelor date
transmise ca parametri. Fie aceasta constant
masca
equ
00001111b.
macro x
local masca
.data
masca equ 00001111b
.code
push ax
mov al, x
and
al, masca
mov x, al
pop ax
endm
538
?
?
539
Dup ce se face nmulirea dintre a si b, se scade din ax var_2, dup care se adun
la ax var_1.
calc
macro a, b, c, d, e, f, rez
push bp
sub sp,4
mov bp,sp
push ax
xor ax,ax
mov al, e
mul f ;;s-a presupus nmulire fr semn
mov [bp].var_1, ax
xor ax, ax
mov al, c
mul d
mov [bp].var_2, ax
xor ax, ax
mov al, a
mul b
sub ax, [bp].var_2
add ax, [bp].var_1
mov rez, ax
pop ax
add sp, 4
pop bp
endm
540
mov ax, a1
add ax, a2
mov sum, ax
pop ax
endm
541
542
sal ax,1
;
;
add ax,bx
;
mov dest,ax ;
pop bx
;
pop ax
axax*2
avem ax=src*8 i bx=src*2
ax src*10
dstax
refacerea regitrilor folosii
endm
543
push bx
mov ax,src
mov bx,ax
imul ax,bx
imul ax,bx
mov dst,ax
pop bx
pop ax
;
;
;
;
;
;
axsrc
bxax (bcsrc)
axax*bx (ax=src^2)
axax*bx (ax=src^3)
dstax
refacerea regitrilor
endm
Sursa poate fi valoare imediat, registru sau zon de memorie, iar destinaia
poate fi registru sau memorie, dar nu poate fi AX sau BX (care vor avea valorile
dinainte de intrarea n blocul respectiv).
mpririi a dou numere i corespunde macrdefiniia xdiv. Aceast
macrodefiniie ca avea patru parametrii:
x - demprit
(surs)
y - mpritor
(surs)
c - ct
(destinaie)
r - rest
(destinaie)
k - test
(destinaie)
Parametrul test va conine dup apelul macrodefiniiei 0 dac mprirea se
putea efectua (mpritorul diferit de 0) i 1 dac mpritorul este 0 (mprirea ar fi
invalid).
; Implementarea macrodefiniiei x/y c,r
xdiv macro x,y,c,r,k
local xdiv_1,xdiv_2
push cx
; salveaz cx
mov cx,y
; cx y
test cx,cx ; test dac bx=0
jnz xdiv_1 ; dac nu atunci se continu
inc cx
; dac da atunci k 1 (eroare)
mov k,cx
jmp xdiv_2 ; salt la sfrit
xdiv_1:
push dx
; salveaz dx
push ax
; salveaz ax
mov ax,x
; ax x
cwd
;axdx,ax(extensia de semn de la 16 la 32
bii)
idiv cx
; mprirea (axct, dxrest)
mov c,ax
; c ax (ctul)
mov r,dx
; r dx (restul)
xor dx,dx
; k 0 (totul e OK)
mov k,dx
pop ax
; refacerea regitrilor
pop dx
544
xdiv_2:
pop cx
endm
; refacerea lui cx
ax,
bx,
cx,
dx,
si,
di,
Macro
ax
bx
cx
dx
si
di
545
to
a1 a2 a3 a4 a5
este :
Setzero
macro a1, a2, a3, a4, a5
mov a1, 0
mov a2, 0
mov a3, 0
mov a4, 0
mov a5, 0
endm
macro a, b
push ax
mov al, a
mov ah, b
mov b, al
mov a, ah
pop ax
endm
546
Swap2
macro a, b
push ax
push bx
mov ax, a
mov bx, b
mov b, ax
mov a, bx
pop bx
pop ax
endm
ir1 < ir 2
AX =
0
ir 1 = ir 2
1
ir 1 > ir 2
Strcmp
macro
push cx
push di
push si
mov si,
mov di,
mov cx,
et1:
mov al,
mov dl,
cmp al,
jne et2
inc si
inc di
loop et1
mov ax,
jmp et4
et2:
jb et3
mov ax,
ax
dx
bx
byte ptr
byte ptr
dl
ds:[si]
ds:[di]
547
jmp
et4
mov
ax, -1
pop
pop
pop
si
di
cx
et3:
et4:
endm
13
548
PROCEDURI
13.1 Reutilizabilitatea
Secvenele repetitive i secvenele repetabile sunt dou lucruri diferite. Dou secvene
repetitive sunt legate de implementarea structurii repetitive n una din forme (for, do-while, dountil) rezolvarea secvenelor repetabile i-a gsit diferite soluii dintre care se enumer:
plasarea secvenei n afara modulului principal si referirea ei n diferite puncte ale
acestuia; limbajul COBOL are soluia elegant prin utilizarea
instruciunii
PERFORM; reutilizabilitatea e legat numai de programul respectiv;
definirea de proceduri, ca uniti program distincte, cu grad de reutilizabilitate extins i
la alte programe; procedura are o list de parametri mprit n trei subliste: sublista
parametrilor ce conin datele iniiale care vor fi prelucrate n procedur, sublista ce
conine rezultatele prelucrrii i sublista de parametri care modul cum a decurs
prelucrarea (starea procedurii); procedura nu returneaz un rezultat, sau returneaz un
rezultat de tip vid;
definirea de funcii n care lista de parametri conine numai date de intrare i rezultatul
prelucrrii este unul singur i va fi returnat, putnd fi utilizat direct ca termen n
evaluarea de expresii; funciile se construiesc n vederea unei reutilizri foarte largi.
549
p1
p2
r1
r2
...
rm
pn
s1 = 1
s2 = 2
sk = k
s1
...
s2
...
sk
550
NumeProcedura
PROC
[{FAR,NEAR}]
Salvare registre
Stocarea rezultatelor
Restaurare registre
ret [n]
NumeProcedura
ENDP
551
par
proc near
mov cl, m
xor ch, ch
lea di, text
lea si, parola
par1:
mov al, byte ptr[di]
caracterul din text n ax
add al, byte ptr[si]
caracterul din parol
add al, cl
caracterului
add al,100
mov [di+m], al
codificat
inc ah
cmp ah, n
jne par2
xor ax, ax
lea si, parola
dec si
par2:
inc di
inc si
loop par1
ret
par
endp
cod
ends
end start
;ncarc
;adun
;adun poziia
;adun o constant
descarc caracterul
552
call sume
sume PROC
call sume
ret
call sume
sume ENDP
Figura 13.3
Call suma
Compara PROC
Call compara
RET
RET
553
Program principal
Definire parametri reali
Procedur (PROC)
Pregtirea transmiterii
parametrilor reali
APEL PROCEDUR (call)
Prelucrarea rezultatelor
prelucrrii
Salvare registre
Prelucrare referind
parametri formali
Stocarea rezultatelor
Restaurare registre
Revenire (RET)
554
gsesc informaii care fac obiectul prelucrrii. Lucrul cu registre este cel mai simplu mod de
transmitere a parametrilor, listele de parametri formali, respectiv, reali, suprapunndu-se din toate
punctele de vedere.
Cazul 2:
Coninutul zonelor de memorie care formeaz parametri reali se transmit pe stiv,
numrul parametrilor fiind fix; parametri formali sunt zonele din stiv care la
procesarea listei au expresii de referire precis construite; aceasta este transmiterea
parametrilor prin valoare; n procedur se lucreaz cu copiile parametrilor reali, aflate
n stiv; rezultatele se depun fie n registre (preferabil), fie pe stiv.
Parametrii reali sunt zone de memorie diferite n programul apelator. Parametri formali
sunt zone ale stivei unde se afl copii ale valorilor parametrilor reali. Cele dou liste se refer la
zone de memorie diferite care au ns acelai coninut. Este cunoscut cazul procedurii de
interschimb a coninutului dintre dou zone de memorie a i b.
Parametrii reali
Procedur de interschimb
A - 15
Stiv
B - 20
[BP + 4] - 15
[BP + 6] - 20
Registrele AX i BX se folosesc pentru interschimb:
AX = [BP + 4]
BX = [BP + 6]
[BP + 4] = BX
[BP + 6] = AX
Cazul 3:
Zonele de memorie ale cror coninut urmeaz s fie prelucrat n proceduri sunt de
tipuri i lungimi foarte diferite; este convenabil pe stiv s se transmit adresele
zonelor de memorie care formeaz lista parametrilor reali se construiete n acest fel
list de adrese a parametrilor reali, n procedur, parametri formali sunt de fapt
variabile pointer care permit referirea din procedur a zonelor de memorie diferite n
programul apelator; acesta este transmitere prin adres.
Procedura de interschimb va realiza corect operaia dac pe stiv se vor gsi adresele
zonelor de memorie a i b; procedura va lucra direct pe ele si ntr-adevr va efectua
interschimbul.
Cazul 4:
Se definete un segment de date comune tuturor procedurilor si programului apelator.
Printr-o ncrcare corect a adresei acestui segment se va opera cu parametri reali
definii n el att din programul apelator, ct i din orice procedur segmentul de date
este comun ntregii operaii. Se realizeaz transmiterea prin referin, variabilele cu
anumii identificatori se afl n segmentul comun aplicaiei i de acolo se utilizeaz
coninutul zonei de memorie.
13.4 Locul procedurilor
555
.code
start:
...
call b1
...
call b2
...
mov ax, 4c00h
int 21h
b1
proc
...
ret
b1
endp
b2
proc
...
ret
b2
endp
a)
b)
;push IP
unde D16 reprezint deplasarea ntre destinaie i instruciunea ce urmeaz lui CALL n programul
apelator.
556
Instruciunea ret efectueaz:
IP = (SP)
SP = SP + 2
Se consider programul:
Parametri
a
b
c
d
s
Parametri
segment
dw
10
dw
15
dw
21
dw
37
dw
?
ends
Stiva
segment
Dw
100h dup (?)
label word
ends
varf
Stiva
Apelator
segment
ASSUME cs:code, ds:parametri, ss:stiva
start:
mov
mov
mov
mov
mov
mov
push
mov
push
mov
push
mov
push
call
mov
add
mov
mov
int
ax, parametri
ds, ax
ax, stiva
ss, ax
sp, offset varf
ax, offset a
ax
ax, offset b
ax
ax, offset c
ax
ax, offset s
ax
NEAR ptr suma
ax, s
ax, d
s, ax
ax, 4c00h
21h
557
Apelator
mov
pop
pop
ret
ends
[bp+ 4], ax
ax
bp
8h
Semnificaie
Plasare adresa (offset) a
Plasare adresa b
Plasare adresa c
Plasare adresa rezultat s
Ape procedura sum
Salveaz baza stivei
Salvare pe stiv valoare registru AX
Refacere registru AX
Refacere registru BP
Reface IP (se pregtete return)
Scoate parametri din stiv
Adresare
[BP+10]
[BP+8]
[BP+6]
[BP+4]
[BP+2]
[BP+0]
[BP-2]
-
Dac procedura se afl n acelai segment i este apelat indirect instruciunea call
realizeaz:
SP = SP 2
(SP) = IP
(IP) = EA
unde EA reprezint adresa efectiv (effective address).
Dac programul apelator se afl ntr-un registru i procedura apelat se afl n alt segment,
instruciunea call realizeaz:
SP = SP 2
(SP) = CS
SP = SP 2
(SP) = IP
Instruciunea ret pentru acest caz realizeaz:
IP = (SP)
SP = SP + 2
CS = (SP)
SP = SP + 2
Dinamica stivei cnd programul apelator se afl n segmentul apelului, iar procedura se afl
n segmentul procedurii este:
Parametri
a
b
segment
dw
10
dw
15
558
c
d
s
Parametri
dw
dw
dw
ends
Stiva
segment
Dw
100h dup (?)
label word
ends
varf
Stiva
Apelator
21
37
?
segment
ASSUME cs:code, ds:parametri, ss:stiva
start:
Apelator
Procedura
suma
suma
procedura
Stiv
mov
mov
mov
mov
mov
mov
push
mov
push
mov
push
mov
push
call
mov
add
mov
mov
int
ends
ax, parametri
ds, ax
ax, stiva
ss, ax
sp, offset varf
ax, offset a
ax
ax, offset b
ax
ax, offset c
ax
ax, offset s
ax
far ptr suma
ax, s
ax, d
s, ax
ax, 4c00h
21h
segment
ASSUME cs:procedura
proc FAR
push bp
mov
bp, sp
push ax
xor
ax, ax
add
ax, [bp+12]
add
ax, [bp+10]
add
ax, [bp+ 8]
mov
[bp+ 6], ax
pop
ax
pop
bp
ret
8h
endp
ends
semnificaie
Adresare
559
Offset a
Offset b
Offset c
Offset s
CS
IP
BP
Ax
Ax
BP
IP
CS
SP = SP +8h
[BP+12]
[BP+10]
[BP+8]
[BP+6]
[BP+4]
[BP+2]
[BP+0]
[BP-2]
-
Dac programul apelator i procedura se afl n segmente diferite, iar apelul este direct,
instruciunea CALL realizeaz:
SP = SP 2
(SP) = CS
SP = SP 2
(SP) = IP
(IP) = (EA)
(CS) = (EA) + 2
Instruciunea ret poate fi definit mpreun cu o expresie constant:
ret
expresie
care evalueaz i devine o valoare de adunare la registru de stiv (SP) ca parte din instruciune
determinnd executarea secvenei:
SP = SP + expresie
pentru revenire n programul apelator:
IP = (SP)
SP = SP + 2
CS = (SP)
SP = SP +2
SP = SP + expresie.
Aceasta este echivalent cu scoaterea din stiv a unui numr de baii specificat prin
expresie; se folosete la eliminare din stiv a parametrilor care au fost pui nainte de apelul
procedurii.
Fcnd modificri asupra coninutului stivei n procedura apelat este posibil revenirea n
programul apelator la alt instruciune i chiar la instruciuni aflate n segment de cod diferit
segmentului programului apelator. Se recomand folosirea acestei faciliti doar pentru protejarea
codului.
560
14
PRELUCRRI N VIRGUL MOBIL
14.1 Scurt istorie a prelucrrilor n virgul mobil
Procesoarele din familia 80x87 au fost construite cu scopul precis de a
crete viteza de lucru a calculatoarelor n operaiile matematice complexe. Pn la
versiunea 80387 coprocesoarele puteau sa existe sau nu n calculatoare. De
exemplu, un procesor 80386 lucreaz foarte bine cu coprocesorul 80287 sau cu
80387. Mai trziu, la apariia procesorului 80486, coprocesorul a fost nglobat n
procesor, pentru mbuntirea performanelor. Astfel, un procesor 80486 conine
un procesor 80387. Instruciunile procesorului 80486 sunt cele ale procesorului
80386, cele ale coprocesorului 80487 i cteva n plus.
Toate coprocesoarele lucreaz insa cu numere reprezentate pe 80 de bii.
Procesoarele nu trebuie sa se ocupe de conversia numerelor pe 8, 16, 32 sau 64 de
bii n cele pe 80 de bii, deoarece instruciunile care mut datele din regitrii
procesorului n cei ai coprocesorului convertesc automat numerele n formatul de
80 de bii.
Unele din numerele de 80 de bii au o semnificaie speciala, ele pot
reprezenta numrul infinit, un numr cu parte fracionar n perioad sau un NaN
(Not a Number). NaN este o valoare care se obine n momentul n care se ncearc
rezolvarea unor calcule de genul 0/0 sau /.
O alt caracteristica a coprocesoarelor este aceea a executrii secveniale a
instruciunilor. De exemplu, dac avem dou instruciuni, cea de-a doua nu este
executat pn cnd prima instruciune nu a fost terminat.
14.2 Resurse
Pentru efectuarea prelucrrilor n virgul mobil este utilizat un coprocesor
sau se construiesc proceduri care efectueaz conversii i calcule cu utilizarea
aritmeticii binare cu biii reprezentnd caracteristica i mantisa.
Astfel dac se aduna numerele
A = 0,37102
B = 0,123104
se parcurg urmtorii pai.
se omogenizeaz numerele, n aa fel nct sa aib acelai exponent:
A = 0,0037104
B = 0,123104
561
M1
E2
M2
dac E1 = E2 atunci M3 = M1 + M2
dac E1 1 vedem cu cat i mrim E3. Z1 reprezint partea ntreag a
mantisei, n acest caz a lui M3.
Dac este utilizat un coprocesor, resursele disponibile ale acestuia sunt:
opt registre ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7; fiecare registru
are o lungime de 10 baii;
o structura de baii, denumit status word, destinat indicatorilor de
condiie; astfel, coprocesorul 8087 are o structura de 16 bii cu
indicatorii de condiie specificai n figura 14.1.
562
Utilizare
Invalid
operation
exception
Denormalized
operand exception
Zerodivide exception
Overflow exception
Underflow exception
Precision exception
Interrupt exception
Condition code 0
Condition code 1
Condition code 2
Stack-top pointer
Condition code 3
Busy signal
563
RR
ceea ce nseamn c ambii operanzi se afl n regitri (pe
stiv) i prelucrrile se efectueaz n unul din urmtoarele doua moduri:
o un operand este conservat iar celalalt va conine rezultatul
prelucrrii ;
o ambii operanzi sunt conservai i rezultatul prelucrrii este
introdus la baza stivei; operanzii conservai, iar vrful stivei
gliseaz.
564
RM
ceea ce nseamn c un operand se afla n registru i altul se
afla n memorie; operandul din registru este copiat n alt registru i la
baza stivei se va gsi rezultatul, fie operandul este modificat i el
reprezint rezultatul prelucrrii; poziia operandului aflat n memorie
determina uneori ca rezultatul prelucrrii sa fie stocat n aceast zona, n
cazul instruciunilor de forma: cod_operatie M,R.
Structura terminal a mnemonicelor indica prin prezena literei p, efectuarea
de operaii de introducere n stiva (push), sau de extragere din aceasta
(pop). Utilitatea acestui mod de lucru este evideniat atunci cnd se
evalueaz expresii i regitrii conin rezultate pariale care se refera
direct, fr a mai fi nevoie de operaii de ncrcare (load) sau memorare
(store).
14.3 Setul de instruciuni
Instruciunile coprocesoarelor din familia 80x87 sunt clasificate n ase
grupe distincte:
instruciuni de transfer al datelor (de ncrcare) ;
instruciuni aritmetice ;
instruciuni de comparare ;
instruciuni transcedentale ;
constante ;
instruciuni de control al procesorului .
Pentru o gestionare corect a operaiilor care se desfoar n coprocesor a
fost implementat structura de control a operaiilor, denumit control word.
Comportamentul acestui registru este asemntor cu cel al registrului de stare.
Registrul de control are o lungime de 16 bii, valorile acestora fiind detaliate n
figura de mai jos:
Utilizare
565
Precision exception mask
Reserved
Interrupt enable mask
0 = Interrupts enabled
1 = Interrupts disabled
Precision Control
00 = 24 bits
01 = reserved
10 = 53 bits
11 = 64 bits
Rounding Control
00 = round to nearest or even
01 = round down
10 = round up
11 = truncate
Infinity Control
0 = Projective
1 = Affine
Reserved
566
567
PVST := PVST + 1
Instruciunile FDIV DST,SRS i FDIVP DST,SRS efectueaz mprirea:
(DST) := (DST) / (SRS)
n plus FDIVP incrementeaz pointerul pentru gestionarea stivei. Pentru
mprirea numerelor ntregi se utilizeaz instruciunea FIDIV.
Pentru obinerea valorii absolute se utilizeaz instruciunea FABS, fr
operanzi care realizeaz operaia:
(ST) := | ST |
Schimbarea semnului se efectueaz de ctre instruciunea FCMS cu
operandul implicit ST, care efectueaz operaia:
(ST) := -(ST)
Pentru extragerea rdcinii ptrate se utilizeaz instruciunea FSQRT cu
operandul implicit ST, care realizeaz operaia descrisa prin:
(ST) :=
(ST )
ST(1)
parte fractionara
ST
568
2 / 2 ) i y R
569
Instruciunea
constanta log2 e .
Instruciunea
constanta log2 10 .
Instruciunea
constanta log10 2.
Instruciunea
constanta loge 2.
570
sau
Fmnem [[destinaie][,sursa]]
Prin utilizarea parantezelor drepte se realizeaz opionalitatea operandului
n expresie. Definirea explicit a operanzilor corespunde construciei:
Fmnem destinaie, sursa
cu semnificaia:
destinaie := destinaie operaie sursa
De exemplu, n instruciunea:
FADD ST(1),ST
avem
ST(1) := ST(1) + ST
corespunde operaiei
ST(i) := ST(i) + ST
iar instruciunea
FADD ST,ST(i)
corespunde operaiei
ST := ST + ST(i)
571
572
ST(0) := ST(0)*2ST(1)
Dac registrul ST(1) conine valoarea 4, coninutul registrului ST(0) va fi
multiplicat de 16 ori. Dac registrul ST(1) conine 3, coninutul registrului ST(0)
va fi mprit la 8.
FLD ST(1)
ST(0)
340
275
?
ST(1)
275
340
?
ST(2)
?
275
?
573
;Program de demo lucru cu coprocesor
;Realizeaza inmultirea a doua numere x1 si x2
; daca exista coprocesor. Altfel afiseaza un mesaj de eroare.
.model small
.286
.data
NuInstalat db 'CoProcesor neinstalat',10,13,'$'
ctrl_87 dw lbffh; precizia =64
x1 dq 12.0
x2 dq 14.0
rezultat dq ?
.code
start:
mov ax,@data
mov ds,ax
mov ax,40h
mov es,ax
mov ax,es:10h
test ax,2
jnz Instalat
mov dx,offset NuInstalat
mov ah,9
int 21h
jmp final
Instalat:
FINIT
FLDC ctrl_87
FLD x1 ;st(0)=x1
FLD x2 ;st(1)=x1 si st(0)=x2
FMUL
FST rezultat ;rezultat=st(0)
final:
mov ax,4c00h
int 21h
end
574
n xk
ex
= k=1 k!
Transferul datelor ctre procedur se va face prin referin. Stiva
coprocesorului va arta astfel:
575
fst st(1)
;
fld1
;
fst st(2)
;
fst st(4)
;
mov cx,1
et: fnop
fld xnr
fmul st(1),st
pune x in st1
pune 1 in st
initializeaza k! cu 1
initializeaza suma cu 1
fxch st(2) ;
mov temp,cx
fimul temp ;
fxch st(2) ;
fld st(1)
;
fdiv st,st(2)
fadd st(4),st
din st4
inc cx
cmp cx,nnr ;
jle et
fxch st(4) ;
fst rez
ret
e_la_x endp
start:
mov ax,@data
mov ds,ax
;
xor cx,cx
call e_la_x ;
mov ax,4c00h
int 21h
end start
schimba st cu st2
; x la k
k!
schimba st cu st2
incarca in st pe x la k
; face impartirea
; aduna rezultatul fractiei la suma
compara cx cu n
; if <= sare la et
aduce rezultatul in st
; duce rezultatul in memorie
14.7 Concluzii
Trebuie realizat un echilibru ntre utilizarea resurselor coprocesorului i
celelalte tipuri de aritmetici, aa fel nct s se obin precizia rezultatelor i n
acelai timp un numr ct mai mic de cicluri main la execuia programului.
576
17
PROGRAMARE MIXT: C LIMBAJ DE ASAMBLARE
17.1 Programul principal este scris n limbaj de asamblare, procedurile
apelate sunt scrise n limbajul C
Variabilele transmise procedurii apelate se definesc cu atributul extrn.
Procedurile apelate se definesc, de asemenea, cu atributul extrn. Se
folosesc pentru apel proceduri scrise n limbajul C pentru a realiza
funcii de intrare/ieire care presupun conversii.
Programul ASM1 adun trei numere. Se apeleaz funcia scanf()
pentru a iniializa trei variabile a, b, c. Dup nsumare se apeleaz
procedura printf() pentru a imprima variabila suma. Se definesc n
programul C variabilele de tip char: format1, format2, format3, format4.
;ASM 1
.model small
.stack 100h
.data
; date externe
extrn c format1:word
extrn c format2:word
extrn c format3:word
extrn c format4:word
extrn c format:word
extrn c a:word
extrn c b:word
extrn c c:word
;date locale
suma dw ?
.code
public _main
; functiile externe apelate
extrn c printf:proc
extrn c scanf:proc
extrn c sablon:proc
extrn c refac:proc
; intrarea in program
_main proc
; apel functie C de formatarea a ecranului
577
call sablon c
; citirea parametrilor de la tastatura
lea ax,format1
call printf c,ax
lea ax,format
lea bx,a
call scanf c,ax,bx
lea ax,format2
call printf c,ax
lea ax,format
lea bx,b
call scanf c,ax,bx
lea ax,format3
call printf c,ax
lea ax,format
lea bx,c
call scanf c,ax,bx
; insumarea celor trei valori
mov ax,a
add ax,b
add ax,c
mov suma,ax
; afisarea rezultatului
lea ax,format4
call printf c,ax,suma
; apel functie C de refacere a ecranului
call refac c
; iesirea din program
ret
_main endp
end
//C1
#include <stdio.h>
#include <conio.h>
char format1[20]="a=";
char format2[20]="b=";
char format3[20]="c=";
char format4[20]="\nsuma=%d\n";
char format[20]="%d";
int a,b,c;
void sablon(void)
{
int i;
clrscr();
578
for(i=0;i<80;i++)
printf("-");
printf("Introduceti datele:\n");
for(i=0;i<80;i++)
printf("-");
printf("\n\n\n");
for(i=0;i<80;i++)
printf("-");
printf("\n");
for(i=0;i<80;i++)
printf("-");
gotoxy(1,4);
}
void refac(void)
{
getch();
clrscr();
}
579
afisare:
mov al,0
mov sirc[bx],al
lea ax,sir
lea bx,sirc
push ax
push bx
call _stringcmp
add sp,4
test ax,ax
jnz diferite
lea ax,m1
call printf c,ax
jmp sfarsit
diferite:
lea ax,m2
call printf c,ax
sfarsit:
ret
_main endp
end
//C2
int stringcmp(char* x,char* y)
{
while(*x==*y)
{
if(*x=='\0')
return 0;
x++;
y++;
}
return *x-*y;
}
580
extrn _stringcat:proc
_main proc
lea ax,sir1
lea bx,sir2
push bx
push ax
call _stringcat
add sp,4
lea bx,format
call printf c,bx,ax
ret
_main endp
end
//C3
#include <conio.h>
char* stringcat(char* s1,const char* s2)
{
char* t=s1;
while(*s1)
s1++;
while(*s1++=*s2++);
return t;
}
char* stringcat(char* s1,char* s2)
{
int i;
for(i=0;s1[i];i++);
for(;s1[i++]=*s2++;);
return s1;
}
581
extrn c scanf:proc
_main proc
lea ax,format1
call printf c,ax
lea ax,format2
lea bx,a
lea cx,b
lea dx,x
call scanf c,ax,bx,cx,dx
mov ax,x
push ax
mov dx,1
call _funct
add sp,2
mov pf,ax
call pf c,a,b
lea bx,format3
call printf c,bx,ax
ret
_main endp
end
//C4
int min(int a,int b)
{
return a<b?a:b;
}
int max(int a,int b)
{
return a>b?a:b;
}
int (*funct(int x))()
{
int (*pfunct)();
switch(x)
{
case 1:
pfunct=min;
break;
case 2:
pfunct=max;
break;
}
return pfunct;
}
582
lea ax,par1
lea bx,par2
call scanf c,ax,bx
endm
mprintf macro par
lea ax,par
call printf c,ax
endm
.stack 100h
.data
format1 db "Maxim = %d",10,13,0
format2 db "a=",0
format3 db "b=",0
format4 db "c=",0
format5 db "%d",0
a dw ?
b dw ?
c dw ?
rez dw ?
.code
public _main
extrn _max:proc
extrn c scanf:proc
extrn c printf:proc
_main proc
mprintf format2
mscanf format5,a
mprintf format3
mscanf format5,b
mprintf format4
mscanf format5,c
push c
push b
push a
call _max
add sp,6
lea bx,format1
call printf c,bx,ax
ret
_main endp
end
//C5
int max(int a,int b,int c)
{
return a>b?(a>c?a:c):(b>c?b:c);
}
583
584
sterg proc
mov ah,0
mov al,2
int 10h
ret
sterg endp
_afis proc
call pozit
mov ax,seg sir
mov ds,ax
mov dx,offset sir
mov ah,09h
int 21h
terminat cu '$'
mov ah,08h
int 21h
call sterg
ret
_afis endp
end
; Stergerea ecranului
; Pozitionare pe ecran
; Afisare mesaj
;
;
;
;
;
Salvarea registrului bp
bp<-sp
ax=par1
ax+=par2
ax+=par3
585
pop bp
ret
_suma endp
end
; Refacere bp
; Iesirea din functie
;
;
;
;
;
;
;
;
;
;
Salvare bp
bp<-sp
di=pa
ax=*pa;
di=pb
ax+=*pb
di=pc
ax+=*pc
Refacere bp
Iesire din functie
586
printf("b=");
scanf("%d",&b);
printf("c=");
scanf("%d",&c);
pa=&a;
pb=&b;
pc=&c;
ps=suma(pa,pb,pc);
printf("suma=%d\n",*ps);
}
;ASM 9
.model small
.stack 100h
.data
rez dw ?
.code
public _suma
_suma proc
push bp
mov bp,sp
mov di,[bp+4]
mov ax,[di]
mov di,[bp+6]
add ax,[di]
mov di,[bp+8]
add ax,[di]
mov rez,ax
mov ax,offset rez
pop bp
ret
_suma endp
end
; ax=*par1+*par2+*par3
; rez<-ax
; ax<-&rez
587
scanf("%d",&v);
x[i]=v;
}
printf("Suma elementelor vectorului = %d",suma(x,n));
}
;ASM 10
.model small
.stack 100h
.code
public _suma
_suma proc
push bp
mov bp,sp
mov cx,[bp+6]
mov si,[bp+4]
xor ax,ax
ciclu:
add ax,[si]
inc si
inc si
loop ciclu
pop bp
ret
_suma endp
end
;
;
;
;
;
;
; }while(i<n)
//C11
/*
Produsul scalar a doi vectori.
*/
#include <stdio.h>
extern int prodscalar(int*,int*,int);
void main(void)
{
int x[40],y[40],v,i,n;
printf("n=");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("x[%d]=",i);
scanf("%d",&v);
x[i]=v;
printf("y[%d]=",i);
scanf("%d",&v);
y[i]=v;
}
v=prodscalar(x,y,n);
printf("Produsul scalar = %d\n",v);
}
588
;ASM 11
; Produsul scalar a doi vectori
.model small
.stack 100h
.code
public _prodscalar
_prodscalar proc
push bp
mov bp,sp
mov cx,[bp+8] ; Numarul de elemente
mov si,[bp+4] ; Adresa primului vector
mov di,[bp+6] ; Adresa celui de-al doilea vector
xor bx,bx
ciclu:
; Bucla repetata de cx ori
mov ax,[si] ; bx+=[si]*[di];
mul word ptr [di]
add bx,ax
inc si
inc si
inc di
inc di
loop ciclu
mov ax,bx
; ax=bx (rezultatul)
pop bp
ret
_prodscalar endp
end
//C12
/*
Suma elementelor unei matrice.
*/
#include <stdio.h>
#define N 5
extern int suma(int x[][N],int m,int n);
void main(void)
{
int x[3][N],v;
int i,j,m,n;
printf("numarul de linii = ");
scanf("%d",&m);
printf("numarul de coloane = ");
scanf("%d",&n);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
printf("x[%d][%d]=",i,j);
scanf("%d",&v);
x[i][j]=v;
}
printf("suma elementelor matricii = %d\n",suma(x,m,n));
589
}
;ASM 12
; Suma elementelor unei
.model small
.stack 100h
.code
c equ 5
public _suma
_suma proc
push bp
mov bp,sp
mov bx,[bp+4]
xor ax,ax
mov dx,[bp+6]
c1:
mov cx,[bp+8]
xor si,si
c2:
add ax,[bx][si]
inc si
inc si
loop c2
add bx,c*2
dec dx
jnz c1
pop bp
ret
_suma endp
end
matrici
//C13
/*
Realizarea unei functii specificate de utilizator (min
sau max) asupra a doua numere introduse de la consola.
Se realizeaza cu aplelu unei functii asm care primeste
ca parametru
functia dorita.
*/
#include <stdio.h>
extern int suma(int*,int*,int(*)(int,int),int);
int max(int a,int b)
{
return a>b?a:b;
}
void main(void)
{
int x[40],y[40],n,i,v;
printf("n=");
scanf("%d",&n);
for(i=0;i<n;i++)
590
{
printf("x[%d]=",i);
scanf("%d",&v);
x[i]=v;
printf("y[%d]=",i);
scanf("%d",&v);
y[i]=v;
}
printf("Suma elementelor maxime = %d\n",suma(x,y,max,n));
}
;ASM 13
; Suma elementelor maxime din doi vectori de elemente
; Functia de comparare e transmisa ca parametru
; (o adresa near)
.model small
.stack 100h
.data
rez dw 0
.code
public _suma
_suma proc
push bp
mov bp,sp
mov cx,[bp+10]
; Numarul de elemente
mov di,[bp+6]
; Adresa celui de-al doilea vector
mov si,[bp+4]
; Adresa primului vector
ciclu:
mov ax,[si]
mov bx,[di]
call word ptr [bp+8] c,ax,bx ; Apel functie de comparare
add rez,ax
; rez+=max
inc si
; Urmatoarele elemente din vectori
inc si
inc di
inc di
loop ciclu
mov ax,rez
; ax<-rez
pop bp
ret
_suma endp
end
591
...
s=0;
for (i=0; i<30000; i++)
for (j=0; j<70000; j++)
for (k=0; k<20000; k++)
if(i= =j)
s+=k*2;
else
s+=k/2;
...
17.3 Concluzii
{
mov bx, k
mov ax, i
cmp ax, j
jz egal
shr bx
egal: nop
shl bx
mov ax, s
add ax, bx
mov s, ax
}
se
592
593
18
DEZVOLTAREA DE APLICAII ORIENTATE
OBIECT IN LIMBAJ DE ASAMBLARE
18.1. Concepte folosite n dezvoltarea programelor orientate obiect
O clas este definit ca abstractizare a trsturilor eseniale ale unei colecii
de obiecte nrudite. Deci o clas este o mulime de obiecte care partajeaz o
structur comun i un comportament comun. Se extinde astfel conceptul datelor
de tip structur, combinndu-se datele cu codul ce le proceseaz.
O clas are dou componente, una static i alta dinamic. Prima
component se refer la proprietile obiectelor caracterizate de clas, i este
reprezentat de datele membre (cmpurile cu nume care posed valoare i care
caracterizeaz starea obiectului n timpul execuiei). A doua se refer la
comportamentul obiectelor clasei, deci la modul n care acioneaz i reacioneaz
acestea, i este constituit din metodele clasei respective.
Un obiect este definit ca materializarea sau concretizarea tipologiei descrise
de o anumit clas. El este un concept, abstractizare sau lucru cu limite precizate i
cu neles pentru problema n cauz.
Clasa
Obiect1
Obiect2
594
595
Clasa de
baza 2
C la sa
de
baza 1
C lasa
de
baza 2
Clasa
derivat
Date i
metode clasa
derivata . . . .
596
597
Numrul implicat n adunare / nmulire este trimis prin adres prin registrul
SI, iar adresa obiectului este trimis prin registrul DI.
Pentru clasa Complex procedurile sunt:
...
adunare_complex proc
push ax
mov ax, [di].nr_int
add ax, word ptr [si]
mov [di].nr_int, ax
mov ax, [di].nr_complex
598
add ax, word ptr [si+2]
mov [di].nr_complex, ax
pop ax
retn
adunare_complex endp
inmultire_complex proc
.data
int_temp dw 0
.code
push ax
mov ax, [di].nr_complex
mul word ptr [si+2]
mov bx, ax
mov ax, [di].nr_int
mul word ptr [si]
sub ax, bx
mov int_temp, ax
mov ax, [di].nr_complex
mul word ptr [si]
mov bx, ax
mov ax, [di].nr_int
mul word ptr [si+2]
add ax, bx
mov [di].nr_complex, ax
mov ax, int_temp
mov [di].nr_int, ax
pop ax
retn
inmultire_complex endp
...
Numrul complex este format din dou date membre, nr_int i nr_complex,
adunarea i nmulirea fiind definite astfel:
(a , a ) (b , b ) (a b , a b )
1 2
1 2
1
1 2
2
(a , a ) (b , b ) (a b a b , a b a b )
1 2
1 2
1 1
2 2 1 2
2 1
dw
0
adunare_integer
599
inm_int
Integer ends
Complex struc
baza
nr_complex
adun_compl
inm_compl
Complex ends
dw
inmultire_integer
Integer <>
dw
0
dw
adunare_complex
dw
inmultire_complex
...
.code
start:
mov ax,@data
mov ds,ax
lea
si, numar1
lea
call
call
lea
call
di,ob_integer
ob_integer.adun_int
;nr_int = 4+10 = 14
ob_integer.inm_int ;nr_int = 14*10 = 140
di,ob_complex
ob_complex.adun_compl
;nr_int = 7+10 = 17
;nr_complex = 5+5 = 10
call ob_complex.inm_compl
;nr_int = 17*10-10*5 = 120
;nr_complex = 17*5+10*10 = 185
sfarsit:
mov ax,4c00h
int 21h
end start
600
601
Id = 1
;folosita de OBJECTS
gasit = 0
;folosita la cautarea in clase de baza
deplasament = 0
;deplasamentul folosit in cazul ;accesarii
unor variabile din
;clasele de baza
baseId = 0
;id-ul clasei de baza la cautarea datelor
;membre
publicDer = 1
;indica
daca
derivarea
se
face
;public (=1) sau private (=0)
;VARIABILE CARE DEPIND DE CLASE (de numele clasei sau de idul ei)
;<numeClasa>Id
id-ul clasei cu numele <numeClasa>
;<numeObiect>Id
id-ul obiectului (EGAL ;INTOTDEAUNA
CU ID-UL CLASEI
;
DE CARE APARTINE!)
;no<Id>
nr elementelor din clasa cu id-ul
<id>
;baseNo<Id>
nr claselor de baza pentru ;clasa cu
id-ul <id>
;disable<Id>Prot
indica daca se foloseste sau nu
;protectia datelor
;
(folosita
in
apelul
functiilor
;membre)
;friend<Id>Of<currId>Id indica, daca exista, prietenia ;intre
clasele cu
;
id-urile <Id> si <curcId>
;depl<baseId>In<currId> indica deplasarea clasei de baza (
<baseId> ) in clasa
;
cu id-ul <currId>
va
602
;creaza variabila de control a protectiei
;clasei
setDisableProt
%currId, 0
;initial protectia
este ;activata
nume struc
;creaza structura
ENDIF
ENDM
603
date MACRO den, tip, v
internDate %currId, den, tip, <v>
ENDM
internDate MACRO id, den, tip, v
No&id = No&id + 1
;alocare data
IFB <v>
den&id&@val@ tip ?
ELSE
den&id&@val@ tip v
ENDIF
;alocare protectie
IFE currProt
;; public
%OUT < define den as public ... >
ELSE
%OUT < define den as private ... >
ENDIF
den&id&Prot = currProt
ENDM
604
den&id&FuncProt = currProt
ENDM
605
606
;aloca obiectul de baza
baseNo&currBaseNo&@base@ den <>
;calculeaza deplasamentul fata de clasa derivata
depl&baseId&In&currId = OFFSET baseNo&currBaseNo&@base@
;mostenire publica
IF publicDer
;declara clasa derivata ca prietena a clasei de baza
friend3 currId, baseId
ENDIF
ENDM
607
mov currOffSet,OFFSET ob
operDreapta movFromOb, unde, %(ob&Id), currOffSet, camp
ENDIF
IFE gasit
;nu s-a gasit
%OUT < **Error** camp is not a member of ob ... >
.ERR
ELSE
gasit = 0
;pt. urmatoarele cautari se revine
;la 0
ENDIF
deplasament = 0
ENDM
operStanga MACRO oper, id, ob, camp, v
IFDEF camp&id&@val@
;se afla direct in ;clasa?
;s-a gasit si se face operatia in functie de protectie
isProt? id, camp
oper id, ob, camp, v
gasit = 1
;l-a gasit
ELSE
;NU, poate se afla intr-o
;clasa de baza
;CAUTARE IN CLASELE DE BAZA:
searchInBase %(baseNo&id), id, camp
IF gasit
;se introduce operatia propriu-zisa
;baseId va contine id-ul la care s-a ajuns in
;cautare
;si a carui clasa cuprinde variabila
isProt? %baseId, camp
;vede
daca
este
;protejata
;in clasa derivata
oper %baseId, ob, camp, v
ENDIF
ENDIF
ENDM
operDreapta MACRO oper, unde, id, ob, camp
IFDEF camp&id&@val@
;se afla direct in ;clasa?
;s-a gasit si se face operatia in functie de protectie
isProt? id, camp
oper unde, id, ob, camp
gasit = 1
;l-a gasit
ELSE
;NU, poate se afla intr-o
;clasa de baza
;CAUTARE IN CLASELE DE BAZA:
searchInBase %(baseNo&id), id, camp
IF gasit
;se introduce operatia propriu-zisa
;baseId va contine id-ul la care s-a ajuns in
;cautare
;si a carui clasa cuprinde variabila
608
isProt? %baseId, camp
;protejata
;vede
daca
este
609
ENDIF
noCurr = noCurr + 1
ENDM
ENDM
searchInBase2 MACRO noCurr, currId, camp
baseId = baseNo&noCurr&Of&currId&Id
searchInBase3 currId, %baseId, camp
ENDM
searchInBase3 MACRO currId, baseId, camp
searchInBase4 camp&baseId&@val@
IF gasit
;la gasit si se calculeaza deplasamentul in
;functie de baseId
addDeplas %(depl&baseId&In&currId)
ENDIF
ENDM
searchInBase4 MACRO den
IFDEF den
;data
cu
denumirea
den
a
fost
;definita
gasit = 1
ENDIF
ENDM
addDeplas MACRO deplCurr
deplasament = deplasament + deplCurr
ENDM
;partea intreaga
610
publicExt <Integer>
public_
date
nr_complex, dw, 0 ;partea complexa
func
Adunare
func
Inmultire
Complex ends
.code
;DEFINIREA METODELOR
classFunc Integer, Adunare
push ax
get ax, nr_int
add ax, word ptr [si]
set nr_int, ax
pop ax
endFunc
Integer, Adunare
classFunc Integer, Inmultire
push ax
get ax, nr_int
mul word ptr [si]
set nr_int, ax
pop ax
endFunc
Integer, Inmultire
classFunc Complex, Adunare
push ax
get ax, nr_int
add ax, word ptr [si]
set nr_int, ax
get ax, nr_complex
add ax, word ptr [di]
set nr_complex, ax
pop ax
endFunc
Complex, Adunare
classFunc Complex, Inmultire
push ax
push bx
get ax, nr_complex
mul word ptr [di]
mov bx, ax
get ax, nr_int
mul word ptr [si]
sub ax, bx
push ax
get ax, nr_complex
mul word ptr [si]
mov bx, ax
get ax, nr_int
mul word ptr [di]
add ax, bx
611
set nr_complex, ax
pop ax
set nr_int, ax
pop bx
pop ax
endFunc
Complex, Inmultire
si, numar1
ob_integer,
ob_integer,
di, numar2
ob_complex,
ob_complex,
sfarsit:
mov ax,4c00h
int 21h
end start
Adunare
Inmultire
Adunare
Inmultire
612
(c)
1988,
1996
Assembling file:
intcomp2.ASM
< Creating class Integer ... >
< define nr_int as public ... >
< define function Adunare as public ... >
< define function Inmultire as public ... >
< Creating class Complex ... >
< Current class is derived from Integer ... >
< define nr_complex as public ... >
< define function Adunare as public ... >
< define function Inmultire as public ... >
Error messages:
None
Warning messages: None
Passes:
1
Remaining memory: 422k
;partea intreaga
613
E:\TOOLS\TASM\WORKING>tasm intcomp2
Turbo Assembler
Version 4.1
Copyright
Borland International
(c)
1988,
1996
Assembling file:
intcomp2.ASM
< Creating class Integer ... >
< define nr_int as private ... >
< define function Adunare as public ... >
< define function Inmultire as public ... >
< Creating class Complex ... >
< Current class is derived from Integer ... >
< define nr_complex as public ... >
< define function Adunare as public ... >
< define function Inmultire as public ... >
< **Error** Member nr_int is not accesible ... >
< **Error** Member nr_int is not accesible ... >
**Error** intcomp2.ASM(96) ISPROT?2(8) User error
**Error** intcomp2.ASM(97) ISPROT?2(8) User error
Error messages:
2
Warning messages: None
Passes:
1
Remaining memory: 422k
Se observ c apar dou erori, una pentru set-ul pe clasa Integer, iar alta
pentru cel pentru clasa derivat Complex. Dac cele dou instruciuni set se terg,
procesul de compilare nu va mai semnala nici un fel de eroare, ceea ce
demonstreaz faptul c accesarea datelor membre private din cadrul procedurilor de
adunare i nmulire sunt corecte datorit apartenenei acestor rutine la cele dou
clase.
18.3.1. Optimizarea codului generat de macrodefiniii
Aa cum se va arta spre sfritul capitolului, codul generat de
macrodefiniii n varianta actual este ineficient. Spre exemplu, secvena de
macroinstruciuni:
set
lea
run
run
ob_integer, nr_int, 4
si, numar1
ob_integer, Adunare
ob_integer, Inmultire
614
lea si, numar1
mov currOffset,offset ob_integer
call Adunare1@func@
mov currOffset,offset ob_integer
call Inmultire1@func@
Dup cum se observ, pentru indicarea instanei curente (cea asupra creia
se realizeaz operaiile) se folosete o dat de tip word, currOffset. Aceasta se
ncarc n mod repetat n registrul BX, deoarece ntre instruciunile prezentate pot
exista i alte instruciuni care afecteaz acest registru. n consecin, codul rezultat
din expandarea macroinstruciunilor este departe de a fi optim.
O optimizare foarte uor de fcut, este aceea de a sacrifica un registru (aa
cum n cazurile anterioare s-a folosit registrul SI), care urmeaz s ia locul
variabilei currOffset, dar care nu mai poate fi utilizat dect cu precauie de ctre
utilizator (trebuie salvat n stiva nainte de blocul de operaii n care se folosete i
restaurat nainte de folosirea uneia dintre macroinstruciuni). Pentru aceasta s-a ales
registrul BX, pentru c acesta oricum se folosete la adresarea bazat din cadrul
macrodefiniiilor set i get.
Dup modificare, macrodefiniiile get i set devin:
;setare valoare
set MACRO ob, camp, v
;verifica daca suntem intr-o functie membra (nu se ;mai
specifica obiectul)
IFB <v>
operStanga movToOb, %curId, curOffset, ob, camp
ELSE
mov bx,OFFSET ob
operStanga movToOb, %(ob&Id), ob, camp, v
ENDIF
IFE gasit
;nu s-a gasit
%OUT < **Error** camp is not a member of ob ... >
.ERR
ELSE
gasit = 0
;pt. urmatoarele cautari se
;revine la 0
ENDIF
deplasament = 0
ENDM
;incarcare valoare
get MACRO unde, ob, camp
;verifica daca suntem intr-o functie membra (nu se ;mai
specifica obiectul)
IFB <camp>
615
operDreapta movFromOb, unde, %curId, curOffset,
ob
ELSE
mov bx,OFFSET ob
operDreapta movFromOb, unde, %(ob&Id), ob, camp
ENDIF
IFE gasit
;nu s-a gasit
%OUT < **Error** camp is not a member of ob ... >
.ERR
ELSE
gasit = 0
;pt. urmatoarele cautari se
;revine la 0
ENDIF
deplasament = 0
ENDM
616
unde modificator poate fi NEAR sau FAR, nsoit sau nu de directiva GLOBAL.
Declaraia metodelor clasei are urmtoarea sintax:
[virtual] nume_metoda : tip = nume_eticheta
617
<1.1>
< >
Prin folosirea motenirii se creeaz clase noi din cele deja existente. Clasa
derivat este o copie a clasei de baz la care se pot aduga noi metode sau
variabile. Metodele adugate pot fi complet noi sau le pot nlocui pe cele cu acelai
nume n clasa de baz. n plus, metodele din clasa nou pot apela metodele din
clasa de baz pe care le nlocuiesc. Nu se pot nlocui date ale clasei de baz.
n continuare se prezint un exemplu de implementare a unei clase derivate
din cea anterioar, n limbaj de asamblare orientat obiect:
GLOBAL Deriv_constructor: PROC
GLOBAL Deriv_actiune: PROC
Deriv STRUC GLOBAL Baza MEHOD{
constructor:WORD = Deriv_constructor
VIRTUAL actiune:WORD = Deriv_actiune
}
TBLPTR
y
DD
0.0
ENDS Deriv
618
Inserarea uneia sau mai multor metode virtuale ntr-o declarare a unei clase
se realizeaz prin prefaarea declarrii metodei cu cuvntul cheie VIRTUAL. Apoi,
n seciunea de date a clasei se insereaz un pointer la VMT folosind directiva
TBLPTR.
Cuvntul cheie TBLINST declar o instan a tabelei metodelor virtuale
(VMT), definind spaiul n memorie pentru aceasta. Simpla declarare a unei
instane VMT nu realizeaz i iniializarea pointerului la VMT pentru diversele
obiecte ale respectivei clase.
DATASEG
TBLINST
Deriv_constructor
TBLINIT Deriv PTR si
ret
ENDP Deriv_constructor
< >
619
Deriv_actiune
call Baza_actiune
ret
ENDP Deriv_actiune
620
Int_Adunare: PROC
Int_Inmultire: PROC
Complex_Adunare: PROC
Complex_Inmultire: PROC
621
ARG @@int:word, @@compl:word
USES ax
CALL si METHOD Integer:Adunare, [@@int]
mov ax, [@@compl]
add ax, [(Complex PTR si).nr_complex]
mov [(Complex PTR si).nr_complex], ax
ret
ENDP Complex_Adunare
PROC Complex_Inmultire
ARG @@int:word, @@compl:word
USES ax, bx
mov ax, [@@compl]
mul [(Complex PTR si).nr_complex]
mov bx, ax
mov ax, [@@int]
mul [(Complex PTR si).nr_int]
sub ax, bx
push ax
mov ax, [@@compl]
mul [(Complex PTR si).nr_int]
mov bx, ax
mov ax, [@@int]
mul [(Complex PTR si).nr_complex]
add ax, bx
mov [(Complex PTR si).nr_complex], ax
pop ax
mov [(Complex PTR si).nr_int], ax
ret
ENDP Complex_Inmultire
...
622
...
DATASEG
ob_integer Integer <4>
ob_complex Complex <7, 5>
CODESEG
start:
mov ax,@data
mov ds,ax
mov si,
CALL si
CALL si
mov si,
CALL si
CALL si
offset
METHOD
METHOD
offset
METHOD
METHOD
ob_integer
Integer:Adunare, 10
Integer:Inmultire, 10
ob_complex
Complex:Adunare, 10,5
Complex:Inmultire, 10,5
sfarsit:
mov ax,4c00h
int 21h
end start
623
2000
5000
624
lea
mov
next1:
push
mov
next2:
mov
mov
mov
si, numar1
cx, contor1
cx
cx, contor2
ob_integer.nr_int, 4
ob_complex.nr_int, 7
ob_complex.nr_complex, 5
nr_int, 4
nr_int, 7
nr_complex, 5
Inmultire
Inmultire
de
625
loop next1
sfarsit:
mov ax,4c00h
int 21h
end start
626
membrilor)
Implementarea
Borland orientat
obiect
100
121
81
27
Motenire
Polimorfism
Funcii virtuale
627
Prima variant de implementare prezint cele mai puine linii de cod i cel
mai mic timp de execuie. Acest lucru este explicat prin lipsa celor mai elementare
concepte ale programrii orientate obiect (implementarea nu ofer nici mcar o
protecie a datelor sau polimorfism). Tot ceea ce scrie programatorul se reflect n
mod identic n codul surs supus asamblrii, singura abatere de la programarea
tradiional n cod de asamblare o constituie includerea pointerilor ctre proceduri
n cadrul structurilor.
Cea de-a doua metod de implementare este prezentat n cele dou
variante, observndu-se ctigul substanial de vitez al formei optimizate. Aceasta
se apropie ca performan de metoda care folosete structuri simple (22 de secunde
de execuie fa de 20), oferind n plus programatorului ncapsulare, polimorfism i
motenire multipl. Prima variant este mult mai lent datorit folosirii unei date
suplimentare pentru deplasare n cadrul structurilor i a salvrilor repetate n stiv a
registrului BX. Dar, aceasta ofer un grad mai ridicat de ncapsulare. Utilizatorul
macroinstruciunilor nu este supus nici unor restricii n folosirea registrului BX,
care n cazul variantei optimizate trebuie salvat i restaurat de fiecare dat innd
cont c i codul expandat de macrodefiniii folosete acest registru. De asemenea,
varianta a doua, din motive de optimizare a codului, necesit ncrcarea explicit n
registrul BX a instanei asupra creia se lucreaz, ceea ce duce la creterea
probabilitilor de apariie a erorilor.
Ultima variant de implementare, cea oferit de firma Borland, ofer
performane medii i acest lucru se explic prin modul n care sunt tratai
parametrii procedurilor. Acetia sunt transmii prin stiv, iar pentru folosirea lor se
rezerv regitri care trebuiesc salvai nainte de ncrcare i restaurai la ieirea din
procedur. Pentru a urmri codul generat, s lum procedura de adunare a
numerelor complexe:
PROC Complex_Adunare
ARG @@int:word, @@compl:word
USES ax
CALL si METHOD Integer:Adunare, [@@int]
mov ax, [@@compl]
add ax, [(Complex PTR si).nr_complex]
mov [(Complex PTR si).nr_complex], ax
ret
ENDP Complex_Adunare
628
CALL si METHOD Integer:Adunare, [@@int]
mov ax, [@@compl]
add ax, [(Complex PTR si).nr_complex]
mov [(Complex PTR si).nr_complex], ax
POP
AX
POP
BP
ret
ENDP Complex_Adunare
629
19
STRUCTURI DE PROGRAME
O structur de program se memoreaz n segmente de date (x), segmente de
stiv (y) i segmente de cod (z) i este definit prin tripletul (nx, ny ,nz), unde:
nx numrul de segmente de date;
ny numrul de segmente de stiv;
nz numrul de segmente de cod.
n continuare se prezint tipurile principale de structuri de program att prin
plasarea n memorie (segmente) ct i n raport cu raporturile dintre proceduri.
19.1 Programul ca singur secven (0, 0, 1)
Aceast structur de program de tip monolit este caracteristic problemelor
simple, crora li se d soluie de ctre un singur programator. Operanzii (variabilele
simple, masivele, tipurile derivate) se definesc n acelai segment n care se afl
secvena de instruciuni executabile.
Programul ca singur secven corespunde i construciilor elaborate de
ctre programatorii nceptori care nu au capacitatea de a structura la nivel de
proceduri sau secvene apelabile, operaii complexe cu caracter repetitiv. Tot att
de bine, acest mod de a soluiona o problem este specific i programatorilor care
urmresc minimizarea salturilor necondiionate, generate de apelurile de proceduri
(instruciunea call) i de revenirile la procedura apelatoare (instruciunea ret).
x+y+z+w
F(x,z,y,w)=
x2+y2+z2+w2
x>0
y>0
z>0
w>0
x<0
y<0
z<0
630
w<0
|x|+|y|+|z|+|w|
n rest
PROC ;
s=a+b+c+d
push bp
mov bp, sp
push ax
mov ax, [bp+4] a ;ax:=0
add ax, [bp+6] b ;ax:=ax+b
add ax, [bp+8] c ;ax:=ax+c
add ax, [bp+10] d ;ax:=ax+d
mov [bp+12], ax
;s:=ax
pop ax
pop bp
ret
endp
d;
c
b
a
proc
push bp
mov bp, sp
push ax
631
push dx
mov ax, [bp+4]
mul [bp+4]
mov [bp+6], ax
pop dx
pop ax
pop bp
ret
endp
Textul surs pentru procedura de calcul a modulului unui numr s=|a| este:
modul proc
push bp
mov bp,sp
push ax
mov ax, [bp+4]
neg ax
mov [bp+6], ax
pop ax
pop bp
ret
endp
632
mov ax, offset y
push ax
mov ax, offset x
push ax
jmp suma
alfa:
cmp x, 0
jz beta
cmp y, 0
jz beta
cmp z, 0
jz beta
cmp w, 0
jz beta
mov ax, offset
push ax
mov ax, offset
push ax
call POW2
mov ax, offset
push ax
mov ax, offset
push ax
call POW2
mov ax, offset
push ax
call POW2
mov ax, offset
push ax
mov ax, offset
push ax
call POW2
mov ax, offset
push ax
mov ax, offset
push ax
mov ax, offset
push ax
mov ax, offset
push ax
mov ax, offset
push ax
jmp suma
xp
x
yp
y
zp
wp
w
s
wp
zp
yp
xp
beta:
mov ax, offset
push ax
mov ax, offset
push ax
call modul
mov ax, offset
push ax
mov ax, offset
mx
x
my
y
633
push ax
call modul
mov ax, offset
push ax
mov ax, offset
push ax
call modul
mov ax, offset
push ax
mov ax, offset
push ax
call modul
mov ax, offset
push ax
mov ax, offset
push ax
mov ax, offset
push ax
mov ax, offset
push ax
mov ax, offset
push ax
mz
z
mw
w
s
w
mz
my
mx
suma:
end
call ADD3
...
;procedura pentru conversia de la binar la ir de caractere
;i reprezentare f(x, y, z, w)
...
mov 4c00h
int 21h
start
x
y
z
w
px
py
pz
pw
mx
my
mz
mw
s
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
2
3
4
1
?
?
?
?
?
?
?
?
?
634
start
x>0
y>0
z>0
w>0
x=0
push
y=0
push
z=0
push
w=0
|x|
push
s=a+b+c+d
x2
|y|
y2
|z|
z2
|w|
w2
push
conversiepush
afisare
push
push
stop
push
push
push
push
635
636
mov
mul
add
mov
mul
add
mov
mul
add
mov
mul
add
mov
ax, x
x
bx, ax
ax, z
y
bx, ax
ax, z
z
bx, ax
ax, w
w
bx, ax
s, ax
...
637
mov si, offset y
maxim:
mov ax, [si]
ciclul2:
cmp ax, [si+2]
jge
salt2
mov ax, [si+2] max
salt2;
inc si
inc si
loop ciclul2
ret
add bx, ax
mov e, bx
mov bx, b
mov si, offset y
mov cx, m
call minim
add bx, ax
mov si, offset y
mov cx, m
call maxim
add bx, ax
mov ax, e
mul bx
mov e, ax
mov ex2, dx
mov bx, c
mov si, offset w
mov cx, m
call maxim
add bx, ax
sub e, bx
sbc ex2, 0 e:=e-(c+max{xi})
mov si offset z
mov cx, k
call minim
mov bx, ax
mov si, offset z
mov cx, k
call maxim
add bx, ax
shl bx, 1
sub e, bx
sbc ex2, 0
638
Denumire
(30)
0
Prod1
Prod2
Prod3
Cant
(4)
1
10
5
2
Pret unitar
(5)
2
2
3
13
Total
are textul surs:
rnd1
filler1
linii
rnd2
filler2
col21
denumire 2
col22
cant2
col23
pret2
col24
struc
db 10
db 60
ends
struc
db
db
db
db
db
db
db
db 10 dup ()
I
30 dup ()
,
4 dup ()
,
5 dup ( )
,
Valoare
(8)
3
20
150
26
196
639
valoare2
col25
rnd3
filler
col31
denumire3
col32
cant3
col33
pretunit3
col34
valoare3
col35
db 8 dup ( )
db ,
struc
db 10 dup ( )
db ,
db Denumire/30
db ,
db CANT
db ,
db PU
db ,
db valoare
db ,
scrie-rand1
scrie-rand2
scrie_rand2
scrie_rand3
scrie_rand2
scrie_rand2
scrie_rand1
scrie_rand4 (I0I1I2I3)
scrie_rand1
640
.
.
ret
serie_rnd6:
.
.
ret
seg
NCOL
NLIN
dw
dw
dw
dw
dw
dw
dw
DATE
EQU 4
EQU 4
7, 5, 8, 13
3, 1, 8, 6
1, 0, 3, 7
4, 5, 11, 2
2, 4, 9, 1
32, 2, 5, 7
4, 9, 7, 4
641
C
D
G
BT
A2
SUMA
VP
VS
i
j
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
ends
3, 5, 21, 17
8, 3, 5, 2
6, 1, 1, 4
9, 11, 2, 5
NLIN dup (NCOL dup(?)) ;
NLIN dup (NCOL dup(0)) ;
NLIN dup (NCOL dup(0)) ;
NCOL dup(0)
;vector
NCOL dup(0)
;vector
?
?
B transpus
patratul lui A
A^2+B
produs
suma
macro a, n, i, j, poz
push ax
push bx
mov ax, i
mul ax, n
mov bx, j
add ax,bx
shl ax, 1
mov bx, offset a
add ax, bx
mov poz, ax
pop bx
pop ax
endm
evw
macro b, j, poz
push ax
push bx
mov ax, offset b
mov bx, j
shl bx, 1
add ax, bx
mov poz, ax
pop bx
pop ax
642
endm
unde i=1,NCOL
Pentru procedurile de efectuare a produsului scalar, programatorul P2
elaboreaz n paralel cu ceilali componeni ai echipei procedura:
prodscal
ciclu:
proc
mov cx, NCOL-1
mov i,0
mov f,0
mov f+r, 0
evw vs,i, poz
mov ax, [poz]
evw g, i, poz
mul [poz]
add f, ax
adc f+2, dx
inc i
loop ciclu
ret
endp
proc
push ax
push cx
mov ax, NLIN
mov i, 0
ciclu1:
push cx
mov j, 0
mov cx, NCOL
ciclu2:
emw
mov
emw
mov
inc
b, i, j, NCOL, poz
ax, [poz]
bt, j, i, NLIN, poz
[poz], ax
j
643
loop ciclu2
pop cx
inc i
loop ciclu 1
pop cx
pop ax
ret
endp
proc
push ax
push ax
mov ax, NLIN
mov i, 0
ciclu 1:
push cx
mov j, 0
mov cx, NCOL
ciclu 2:
emw AP, i, j, NCOL, poz
mov ax,[poz]
emw BT, i, j, NCOL, poz
add ax,[poz]
emw MS, i, j NCOL, poz
mov [poz], ax
inc j
loop ciclu 2
pop ax
inc d
loop ciclu 1
ret
endp
644
A1
A1
A2
A3
A4
A5
A6
A7
Ax+1
at elaborare procedura n
at+1 elaboreaz programul apelator
645
struc
dw
db
dw
dw
dw
dw
dw
dw
?
30 dup (?)
?
?
?
?
?
?
646
Proceduri apelate:
Pindex pentru localizare articol dup cheie;
Pscrie pentru rescrierea articolului dezactivat;
d) se scrie procedura pentru creare prin adugare de articol i se ncarc
fiierul fimat care este sursa de baz pentru toi programatorii. Ei au
obligaia de a-l copia i de a-l utiliza n programele lor proprii.
e) se scrie procedura de afiare a fiierului.
f) se scrie procedura de numrare a articolelor din fiier i de afiare a
numrului de articole.
Fiecare i definete i structurile proprii n segmente. n final exist n
proceduri i m segmente de date.
f2
fn-1
fn
647
f1
...
call f1
call f2
...
call fn
mov ax,4c00h
int 21h
proc
...
ret
endp
f2
proc
...
ret
endp
fn
...
proc
...
ret
endp
dw f1, f2, f3
dw f4, f5, f6
...
dw fn-2, fn-1, fn
648
f0
vi
fi
fj
649
fi
fj
fk
Se asociaz acestui
arborescent din figura 19.7.
sistem
de
perechi
f0
Vk=1
f1
Vk=2
f2
Vk=3
f
structura
650
f0
V1=1
V2=1
V3=1
V2=1
V4=1
f1
f2
f3
V3=1
f4
f5
f6
V4=1
f7
f8
@data
ax
1
1
651
jz salt_21
cmp v3, 1
jz salt_23
call f1
jmp final
salt_23:
call f2
jmp final
salt_21:
cmp v4, 1
jz salt_31
call f3
jmp final
salt_31:
call f4
jmp final
salt_11:
cmp v2, 1
jz salt_22
cmp v3, 1
jz salt_32
call f5
jmp final
salt_32:
call f6
jmp final
salt_22:
cmp v4, 1
jz salt_3y
call f7
jmp final
salt_3y:
call f8
final:
mov ax, 4c00h
int 21h
end start
652
f1
f2
f3
f4
f5
f6
f7
f8
fn
f3
f2
f1
653
cmp v, a3
jz salt_3
...
cmp v, an
jz salt_n
call fn1; fn1=fn+1
mov ax, 4c00h
int 21h
salt_1:
call f1
mov ax, 4c00h
int 21h
salt_2:
call f2
mov ax, 4c00h
int 21h
...
salt_n:
f1
f2
fn
fn1
call fn
mov ax, 4c00h
int 21h
proc
...
ret
endp
proc
...
ret
endp
...
proc
...
ret
endp
proc
...
ret
endp
end nume_program
654
- prin scanare B3
- concatenare de fiiere B4
- Calcul salarii C
- pentru un salariat C1
- pentru salariaii unui compartiment C2
- pentru toi salariaii C3
- Actualizare D
- modificare salariu brut D1
- modificare impozit D2
- modificare vechime D3
- modificare volum produse D4
- Afiare rezultate E
- pentru un salariat E1
- pentru toi salariaii E2
- afiare nume i salariu net E3
- afiare toate datele E4
B1 B2
B3 B4
C1 C2 C3
D1 D2 D2 D4
E1 E2 E3 E4
655
f0
C1(1, 2, 3, 4)
1
2
3
C3(1, 2, 3, 4)
C2(1, 2)
f1
f2
f3
f4
f5
f6
4
C4(1)
f7
f8
C5(1, 2, 3, 4, 5)
f9
f10 f11
f12
656
C1=2
C3=1
f1
C1=3
f2
C3=2
f3
C3=3
f4
C5=1
f7
C5=2
f8
f5
C5=3
f6
f9
C5=4
f10
f11
f12
657
fk
C=1
N
fi
fj
C1
N
f1
f2
C2
C3
D
f3
N
f4
C1:= C1+
D
f6
f5
658
q1
f2
q2
f3
f4
f5
q3
q4
q5
659
f1 f2 q3 q4 q5
q1 q2 q3 q4 q5
q1 q2 f3 f4 f5
Mai nou, se construiesc structuri de tip reea cu reluarea
prelucrrilor de la toate punctele de prelucrare, figura 19.18:
f0
f1
C=1
f2
C=1
f3
C=1
fn
660
f0 f1 f2 f3 f1 f2 f3 f4 f1 f2 f1 f2 f3 f4 f5
Cu ct structura produsului este mai mare, cu att se
impune gsirea unor modaliti de simplificare a reprezentrii
interaciunilor dintre proceduri.
19.8 Concluzii
La soluionarea unei probleme se va alege acea structur
care genereaz numrul cel mai mic de apeluri si de reveniri n
programele apelatoare. Cunoaterea celor mai importante tipuri
de structuri de programe creeaz premisele comparrii ntre
structuri cu proprieti care nu difer semnificativ din punct de
vedere al performanelor n vederea lurii deciziei care s
propage la un numr ct mai mare de utilizatori efecte pozitive.
20
OPTIMIZAREA PROGRAMELOR
Optimizarea programelor reprezint una din direciile spre care se
concentreaz realizatorii de software. Exist numeroase aspecte ale optimizrii
programelor: optimizarea timpului de execuie, optimizarea dimensiunii
operanzilor, optimizarea textului surs etc. Toate aceste criterii de optimizare,
considerate cu diferite ponderi, contribuie la definirea conceptului de optimizare a
unui program.
Compilatoarele pentru limbajele evoluate (C, C++, Pascal etc) conin
faciliti de generare de cod executabil optimizat n timp de execuie, n dimensiune
a codului, sau combinaii ntre acestea. Datorit specificaiilor de limbaj, la nivel de
asamblare nu exist asemenea faciliti ncorporate n asambloare, de aceea
aspectele de optimizare revin n exclusivitate programatorului.
n materialul de fa s-a tratat problema optimizrii timpului de execuie,
care survine uneori n defavoarea dimensiunii codului. S-a considerat aceast
abordare deoarece la arhitecturile actuale, memoria nu mai este, n general, o
resurs critic. Resursa critic devine timpul, mai ales la aplicaiile de prelucrare n
timp real, la prelucrri grafice, la jocuri etc.
661
662
se execut n 2 cicluri.
663
664
cnd operandul are adresa efectiv un numr impar, "forarea" la baitul urmtor cu
adresa numr par presupune adugarea a 4 cicluri. Instruciunea
mov SUMA, ax
665
bp
bp,sp
ax,[bp+4]
ax,[bp+6]
ax,[bp+8]
bp
PROC FAR
bp
bp,sp
cx
bx
cx,[bp+6]
bx,[bp+8]
ax,0
add
al,[bx]
ah,0
bx
ciclu
cx
666
pop
pop
ret
generare
bx
bp
ENDP
al,[bx]
ah,0
bx
ciclu
V k0 n1 k1 ... n p k p
unde:
k0
-numrul instruciunilor executate o singur dat;
ni
-numrul de repetri ale buclei de program i;
ki
-numrul de instruciuni cuprinse n bucla de program i.
Valoarea sa este V=11+4*n.
Exist proceduri n care apar comparaii i se efectueaz selecii ale
secvenelor. Se noteaz P j probabilitatea ca o condiie Cj s fie ndeplinit, caz n
care se execut o secven avnd volumul Vt. Numrul repetrilor testului pentru
condiia Cj este nj.
Volumul operaiilor este dat de relaia:
V Pj Vf 1 Pj Vt n j .
Volumul de operaii apare ca un numr mediu de operaii care se vor executa n
timp. Procedura:
trans PROC
mov
cmp
jz
cmp
jb
cmp
ja
and
mov
urmat:
NEAR
al,[si]
al,0
final
al,'a'
urmat
al,'z'
urmat
al,NOT 20h
[si],al
667
inc
jmp
final:
ret
trans ENDP
si
trans
Instruciunea
Mov al,[si]
Cmp al,0
jz final
Cmp al,a
jb urmat
Cmp al,z
ja urmat
And al,NOT 20h
Mov [si],al
Inc si
Jmp trans
Ret
Tabelul 20.1.
Numr de repetri mediu
M
M
M
M
0.033*M
0.967*M
0.967*M
0.96*M
0.96*M
M
M
1
668
pe care fiecare operaie o induce. Un transfer de date, intuitiv este mai simplu dect
o nmulire, iar apelul unei proceduri este mai complex dect o implementare.
Se accept ipoteza conform creia complexitatea operaiilor este strns
legat de numrul de cicluri main asociate. Diversitii de instruciuni i
corespunde o multitudine de numere de cicluri. Mai mult, tipurile de adresare
modific numrul de cicluri pentru fiecare instruciune. Instruciunile care
manipuleaz un volum redus de informaie sau au operanzi prefixati sunt puse n
coresponden cu un numr redus de cicluri. Instruciunile care au adrese ce sunt
calculate dup formule complexe, care impun regsiri, necesit un numr de cicluri
main superior.
Pentru a reflecta mai exact efortul de execuie, volumul programului se va
exprima ca numr de cicluri main. Astfel, secvena:
.......................
mov
ds,ax
; 2 cicluri masina
xor
ax,ax
; 3 cicluri masina
inc
ax
; 2 cicluri masina
cmp
ax,20
; 3 cicluri masina
...............................
NEAR
cx
cx,0ffffh
al,0
scasb
eroare
;
;
;
;
;
;
2 cicluri
10 cicluri
4 cicluri
4 cicluri
n*(6+15) cicluri
8 cicluri pentru salt, 4 cicluri
ax,0ffffh
ax,cx
ax
di
di
SHORT final
;
;
;
;
;
;
4
3
2
2
2
1
di,0
es,di
; 4 cicluri
; 2 cicluri
cx
; 8 cicluri
; 8 cicluri
cicluri
cicluri
cicluri
cicluri
cicluri
ciclu
669
ax,0
ax,ax
ax,ax
; 4 cicluri
; 3 cicluri
; 3 cicluri
rezult necesitatea de a utiliza una din ultimele dou variante, dei prima
instruciune este mai sugestiv.
La tipul de adresare indexat este necesar incrementarea unui registru cu o
raie egal cu lungimea zonei de memorie care este referit. Dac raia este o
unitate, din secvena:
add
inc
si,1
si
; 4 cicluri
; 2 cicluri
rezult c este avantajoas utilizarea instruciunii inc si, efectul fiind major mai
ales pentru faptul c referirea este proprie unei secvene executate repetitiv.
Dac raia cu care se modific registrul index este un numr oarecare,
repetarea instruciunii inc registru este ineficient. Se opteaz spre una din
variantele din secvena:
add
si,57
add
si,bx
initializat mov
add
si,ratia
bx
fost
De cele mai multe ori nu este posibil alocarea unui registru pentru
memorarea raiei i se definete o constant simbolic ( RATIA EQU 57) dup care
incrementarea este realizat prin add si,RATIA.
Lucrurile devin mult mai simple dac se pune problema alegerii modalitii
de a nmuli un numr cu 2k sau de a-l mpri prin 2k. Pentru nmulirea numrului
79 aflat n registrul AX cu 32 se alege secvena:
mov
mov
cl,5
ax,79
670
sal
ax,cl
; 8+4*5 cicluri
ntruct secvena:
mov
bl,32
mov
al,79
cbw
b
mul bl
; 2 cicluri
; 71 cicluri
671
bx,ax
al,operand_bait
ax,bx
672
ax,a
ax,b
ax,c
E1,ax
ax,d
E1
prod1,ax
prod1+2,dx
ax,c
c
ax,E1
dx,0
E1
dx,dx
ax,prod1
dx,prod1+2
E,ax
E+2,dx
;5
;7
;7
;3
;7
;24
;3
;3
;5
;24
;7
;7
;25
;2
;7
;7
;3
;3
ine seama de ceea ce conin registrele dup efectuarea operaiilor i utilizeaz acest
coninut. Este puin probabil ca programatorul s repete de patru ori secvena:
mov
add
add
ax,a
ax,b
ax,c
673
cx,22
ax,0
si,0
ax,x[si]
si
ciclu
total,ax
ax,0
si,0
cx,22
al,x[si]
si
ciclu
cx,37
ax,ax
si,si
; 4 cicluri
; 3 cicluri
; 3 cicluri
al,x[si]
si
ciclux
;18 cicluri * 37
; 2 cicluri * 37
; 37 * 9 cicluri sau 5 cicluri
674
mov
suma,ax
; 14 cicluri
mov
cx,37
; 4 cicluri
xor
ax,ax
; 3 cicluri
xor
si,si
; 3 cicluri
cicluy:
add
al,y[si]
; 18*37 cicluri
inc
si
; 2*37 cicluri
loop cicluy
; 9*37 sau 5 cicluri
mov sumy,ax ; 14 cicluri
;
;
;
;
4
3
3
3
cicluri
cicluri
cicluri
cicluri
;
;
;
;
;
;
18*37 cicluri
18*37 cicluri
2*37 cicluri
9*37 cicluri sa 5 cicluri
14 cicluri
14 cicluri
necesit un volum
V=13+37*47+5+28=1785
de cicluri (8088).
Dac numrul de elemente ale unui ir este par se poate njumti numrul
de repetri prin calculul a dou sume (suma elementelor cu poziie par i suma
elementelor cu poziie impar). La ieirea din ciclu printr-o nsumare se obine
rezultatul dorit.
Secvena:
mov
cx,2*N
xor
ax,ax
xor
si,si
ciclu:
add
ax,x[si]
inc
si
inc
si
loop ciclu
mov
sum,ax
;4 cicluri,
; 3 cicluri
; 3 cicluri
;
;
;
;
;
N constanta simbolica
18*2*N cicluri
2*2*N cicluri
2*2*N cicluri
9*2*N cicluri sau 5 cicluri
14 cicluri
675
bx,0
ax,ax
ax,2
bx,ax
;1
;2
;3
;4
676
alfa
10
20
?
ax,x
ax,b
z,ax
ah,4ch
21h
este interpretat ca generatoare de cod mort dac este inclus chiar ntr-o structur
repetitiv, pentru c att timp ct ax va conine 5 i se va compara cu valoarea zero,
secvena etichetat cu alfa nu se va executa. Volumul de operaii nu este influenat
dac se ia n considerare coeficientul zero al probabilitii acestei secvene inactive.
677
ax,a
bx,b
cx,c
ax,bx
ax,cx
e,ax
;5
;5
;5
;2
;2
;3
cicluri
cicluri
cicluri
cicluri
cicluri
cicluri
ax,a
ax,b
ax,c
e,ax
;5
;7
;7
;3
cicluri
cicluri
cicluri
cicluri
678
dx,dx
ax,a
ax,b
ax,c
bx,ax
ax,a
ax,b
ax,c
bx
;2 cicluri
;5 cicluri
;7 cicluri
;7 cicluri
;2 cicluri
;5 cicluri
;7 cicluri
;7 cicluri
;21 cicluri
dx,dx
bx,b
cx,c
si,a
ax,si
ax,bx
ax,cx
bx,ax
ax,si
ax,bx
ax,cx
bx
;2 cicluri
;5 cicluri
;5 cicluri
;5 cicluri
;2 cicluri
;2 cicluri
;2 cicluri
;2 cicluri
;2 cicluri
;2 cicluri
;2 cicluri
;21 cicluri
se obin 52 cicluri.
Numrul de cicluri necesare pentru execuia unei instruciuni cu operanzi
din memorie este mai mare dect n cazul n care operanzii s-ar afla n regitrii.
Pentru reducerea timpului de execuie, se va urmri pstrarea rezultatelor
intermediare n regitrii liberi, printr-o alocare optim a acestora.
Conform acestui principiu, secvena pentru calculul expresiei :
2
E=(a+b+c)*(a+b+c-d)+(c +a+b+c)/(a+b+c)
devine, prin utilizarea regitrilor BX, SI i DI, urmtoarea:
mov
add
ax,a
ax,b
;5 cicluri
;7 cicluri
679
add
mov
sub
mul
mov
mov
mov
mul
add
adc
div
xor
add
adc
mov
mov
ax,c
bx,ax
ax,d
bx
di,ax
si,dx
ax,c
c
ax,bx
dx,0
bx
dx,dx
ax,di
dx,si
E,ax
E+2,dx
;7 cicluri
;2 cicluri expresia E1
;7 cicluri
;21 cicluri
;2 cicluri
;2 cicluri
;5 cicluri
;24 cicluri
;2 cicluri
;7 cicluri
;14 cicluri
;2 cicluri
;2 cicluri
;2 cicluri
;3 cicluri
;3 cicluri total 117 cicluri
680
21
DESIGNUL LIMBAJELOR DE ASAMBLARE
21.1 Cerine ale designului
Limbajele de asamblare apar ca rezultat al proiectrii microprocesoarelor.
Limbajele evoluate de programare permit accesul la toate resursele sistemelor de
calcul. Performana software este influenat de modul n care a fost proiectat, de
limbajul n care este elaborat i de facilitile oferite de limbajul de asamblare, la
care se ajunge n final. Designul limbajelor de asamblare reprezint un nou mod de
abordare a construirii acestora n vederea ameliorrii performanei software
aplicativ.
Limbajele evoluate de programare elimin suportul nvrii programrii n
limbaj de asamblare pentru a avea acces la toate resursele sistemelor de calcul.
Utilizarea corect a funciilor din bibliotecile standard din programele scrise n
limbajele C++ sau PASCAL ofer programatorilor posibilitile de acces la orice
nivel al resurselor.
n acest nou context, studierea unui limbaj de asamblare se justific pentru
eficientizarea unor secvene de program. Exist posibilitatea de a introduce direct
n textele surs C/C++ secvene asm.
O alt motivaie este nelegerea exact a unor mecanisme de manipulare a
informaiei (lucru pe stiv, lucru cu variabile pointer, definirea i utilizarea
funciilor virtuale).
Dac au existat perioade n care limbajul de asamblare a fost considerat un
produs natural, uneori imperfect, al procesului de proiectare al procesoarelor, acum
se pune i problema de a realiza microprocesoare pornind de la un limbaj de
asamblare dat. Limbajul de asamblare este definit aa fel nct s asigure eficiena,
msurat statistic, fie la implementarea unor mecanisme noi de gestiune a
memoriei, fie n generarea de secvene compacte, fie n reducerea duratei de
execuie a prelucrrilor. n continuare sunt analizate aspecte de baz ale designului
limbajelor de asamblare. Programele scrise ntr-un limbaj de asamblare proiectat cu
luarea n considerare a anumitor criterii de performan, vor propaga efecte pozitive
n toate fazele realizrii codului surs i ale utilizrii software-ului la beneficiari. Se
681
2k
*100
682
Biii
T T T
7 6 5
T
4
T
3
T
2
d
1
w
0
M M
7 6
reg
5 4 3
r/m
2 1 0
683
d - direcie de parcurgere;
w - tip operand (bait/cuvnt);
MM - interpretarea deplasrii;
reg - registre (semiregistre) codificate;
r/m - tipologii expresii de adresare.
Limbajele de asamblare mai vechi, datorit numrului mare de registre i a
aritmeticilor implementate, au regrupat expresiile de adresare pe un numr mai
restrns de bii. Gradul de dependen a cmpurilor din structura instruciunilor era
foarte slab.
Limbajul de asamblare a microprocesorului convenional x86 are definit un
grad de dependent ridicat ntre elementele din structura instruciunii. Astfel,
deplasarea este interpretat funcie de cmpul w (cmpul MM depinde de cmpul
w), iar cmpul reg depinde ca interpretare tot de cmpul w. Cmpul r/m depinde
de cmpul MM. Dac valoarea MM este 11, cmpul r/m este interpretat reg.
684
685
686
21.5 Concluzii
Designul limbajului de programare cu luarea n considerare a finalitii,
scrierea de programe, determin proiectarea unui limbaj pentru utilizator.
Numeroase dificulti care apar n asamblare, la generarea formei interne a
instruciunilor, sunt probleme independente de programator. Odat rezolvate
corect, programul asamblor va opera asupra unei mulimi de programe n cretere,
propagnd efectele pozitive ale limbajului.
Dac la proiectare sunt luate n considerare i elemente de compresie a
programelor n cod main, limbajul de asamblare ofer o trstur benefic tot la
nivelul utilizatorilor finali. Preocuprile de design pentru limbaje de asamblare
capt acum o nou caracteristic, aceea de a fi deschis spre utilizatori. Opiunea
spre neomogenitate de tratare a instruciunilor nu determin complicaii la nivelul
utilizatorilor. La nivelul celor care implementeaz limbajul de asamblare, fiecare
neomogenitate se traduce n modalitate distinct de tratare. Diversitii de tipuri de
instruciuni i va corespunde o cretere a complexitii programului asamblor.
Pentru a obine rezultate cu nivel de stabilitate ridicat este necesar crearea
unei baze de programe scrise n limbaj de asamblare care s includ ct mai multe
stiluri de programe i ct mai multe tipuri de probleme rezolvate.
Ca i n cazul altor limbaje, designul limbajelor de asamblare ia n
considerare meninerea unui nivel ridicat al ortogonalitii instruciunilor. Studiul
efectuat acum a presupus ortogonalitatea deja existent a instruciunilor din
limbajul de asamblare asociat microprocesoarelor x86, fr a se proceda la
definirea de noi instruciuni sau noi tipuri de expresii de adresare. Dac se vor
efectua n viitor i aceste modificri, designul limbajului de asamblare capt un
687
688
22
ELEMENTE DE GRAFIC
22.1 Istoric al adaptoarelor grafice
Imaginea pe care un computer o reprezint cu ajutorul unui monitor a fost
nc de la nceputurile erei informatice cea mai important metod utilizat pentru
a interaciona cu utilizatorul. Ca multe alte familii de calculatoare, cele compatibile
IBM-PC folosesc n acest scop un dispozitiv electronic numit adaptor grafic sau
plac video i dispozitivul de afiare propriu-zis (monitorul, ecranul cu cristale
lichide i altele).
Sistemele pentru afiarea informaiei s-au dezvoltat foarte mult ncepnd cu
monitoarele monocrome folosite pentru procesarea de text i sistemele bazate
exclusiv pe modul text din jurul anilor 1970.
n anul 1981 compania IBM a introdus adaptorul grafic color CGA (Color
Graphics Adapter). Acest sistem era capabil s reprezinte patru culori i avea o
rezoluie de 320x200. Dei adaptoarele CGA ofereau faciliti pentru grafic,
aceste faciliti erau mult prea simple comparativ cu nivelul cerinelor pentru
procesare de text, procesare grafic sau alte aplicaii grafice sofisticate.
n anul 1984 compania IBM a introdus adaptorul grafic EGA (Enhanced
Graphics Adapter). Acest adaptor, cu performane mult mai bune dect
precedentul, oferea o rezoluie mult mbuntit de 640x350 de pixeli i
posibilitatea de a reprezenta 16 culori simultan.
n 1987 compania IBM a fcut public ceea ce urma s devin standardul
minim acceptat, pstrat i astzi, i anume adaptorul VGA (Video Graphics
Adapter). Rezoluia maxim a acestui adaptor depinde de numrul de culori
afiabile simultan. Astfel, se poate opta ntre 640x480 de pixeli cu 16 culori
simultane sau 320x200 de pixeli cu 256 de culori simultane. Toate calculatoarele
actuale compatibile IBM-PC au un adaptor grafic compatibil VGA.
n 1990 compania IBM a introdus adaptorul grafic extins XGA (Extended
Graphics Array), ca succesor al sistemului 8514/A, propriu IBM. O versiune
ulterioar a acestui adaptor, XGA-2, oferea o rezoluie de 800x600 pixeli n mod
true color, aproximativ 16 milioane de culori, sau 1024x768 de pixeli n mod
high color, adic 65536 de culori afiabile simultan.
Cele mai multe adaptoare grafice vndute n ziua de azi sunt descrise ca
SVGA (Super Video Graphics Array). Iniial SVGA a nsemnat doar ceva mai
bun dect VGA, diveri productori ncercnd s impun propriul standard.
689
690
Tipul de adaptor
CGA
CGA
CGA
CGA
CGA
CGA
CGA
Monochrom
EGA
EGA
EGA
EGA
VGA
VGA
691
19
VGA
=
=
=
=
=
1;
2;
3;
4;
5;
.model SMALL
.code
Wich_adapter PROC
mov
ax, 1B00h
int
10h
cmp
al, 1Bh
; al va fi 1Bh pentru VGA
jne
TestIfEGA
mov
ax, VGA
jmp
SHORT DoneAdapter
692
TestIfEGA :
mov
mov
test
jz
mov
jmp
ax, 40h
es, ax
BYTE PTR es:[87h], 0FFh
TestIfCGAorHGC
ax, EGA
SHORT DoneAdapter
TestIfCGAorHCG:
; mai intai obtine flag-ul echipamentului
int
11h
and
al, 30h
; verifica modul video initial
cmp
al, 30h
jne
ItIsCGA
mov
cx, 800h
mov
dx, 3BAh
TestIfHGC:
in
al, dx
; in HGC, bit-ul 7 al port-ului 3BAh
test al, 80h
; va fi 1 in timpul retragerii
verticale
jnz
ItIsHGC
; cicleaz pentru a vedea dac bitul
devine 1
loop TestIfHGC
;altfel este MDA
mov
ax, MDA
jmp
SHORT DoneAdapter
ItIsHGC:
mov
ax, HGC
jmp
SHORT DoneAdapter
ItIsCGA:
mov
ax, CGA
DoneAdapter:
ret
WichAdapter ENDP
END
693
694
100h
.start
push ds
pop es
mov
PLoop:
;
;
ax,ax
;
di,offset
cx,64
xor
mov
stosb
stosb
stosb
inc ax
loop PLoop
mov
; asigur ds=es
int
mov
xor
dx,offset Palette
bx,bx
695
ALoop:
mov
mov
int
cx,64
ax,1012h
10h
;
;
;
mov
mov
mov
di,14464
call Fade
mov
cx,10
mov al,32
push cx
mov cx,128
rep
stosb
add di,192
pop cx
loop ALoop
call Fade
xor
int
ah,ah
16h
; ateptm o tast
mov
int
ax,0003h
10h
.exit
; ieire n DOS
proc near
Fade
stosb
loop PLoop2
add di,192
pop cx
loop PLoop1
ret
endp
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
Palette
dup
; paleta de culori
Fade
PLoop1:
PLoop2:
mov cx,50
push cx
mov cx,64
mov al,cl
dec al
stosb
768,?
696
.end
;
;
;
;
;
dataseg
DB 0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63
;
;
;
;
registru de stare
bit de sincronizare vertical
citete starea
ateapt sincronizarea
; citete starea
697
; ateapt sincronizarea orizontal
proc HorizontalSync near
push
EAX EDX
mov
DX,03DAH
mov
AH,1
@@1: in
AL,DX
test
AL,AH
jnz
@@1
@@2: in
AL,DX
test
AL,AH
jz
@@2
pop
EDX EAX
ret
endp HorizontalSync
;
;
;
;
registru de stare
bit de sincronizare orizontal
citete starea
ateapt sincronizarea
; citete starea
698
in
AL,DX
mov
[EDI],AL
ret
endp GETRGB16
;
;
;
;
; deactiveaz ntreruperile
; 03C8h = adresa registrului VGA PEL
; tabela de culori VGA
;
;
;
;
03C9h
scrie
scrie
scrie
; activeaz ntreruperile
; dezactiveaz ntreruperi
; tabela de culori EGA
;
;
;
;
;
; activeaz ntreruperi
699
; seteaz valori implicite RGB (mod cu 16 culori)
; modific [EAX EBX ECX EDX ESI]
proc RestoreVGA near
mov
EBX,0
mov
ECX,16
mov
ESI,OFFSET EGACOLOR
call SetDAC16
ret
endp RestoreVGA
;
;
;
;
index de start
numr de culori
tabela de culori implicit
seteaz palet culori
700
proc SetDAC256 near
mov
BX,CX
shl
CX,1
add
CX,BX
call
VerticalSync
cli
mov
DX,03C8h
PEL
out
DX,AL
inc
DX
rep
outsb
sti
ret
endp SetDAC256
; dezactiveaz ntreruperi
; 03C8h = adres registru scriere VGA
; dezactiveaz ntreruperi
end
701
702
rezoluia orizontal este mai mic de 1024 se va pierde foarte mult memorie video
n acest mod.
Procedura de trasare a unei linii prezentat mai jos folosete, ca optimizare,
testarea faptului c ambele puncte extreme ale liniei sunt n aceeai seciune. Dac
ambele puncte sunt n aceeai seciune, atunci nu este necesar schimbarea
seciunii. Dac ele nu sunt n aceeai seciune, atunci pentru fiecare punct se
testeaz depirea seciunii curente.
.486
code
PgDown
push
push
xor
mov
add
mov
call
pop
pop
endm
PgUp
macro
bx
dx
bx,bx
dx,cs:winpos
dx,cs:disp64k
cs:winpos,dx
cs:winfunc
dx
bx
macro
push
push
xor
mov
sub
mov
call
add
inc
pop
pop
bx
dx
bx,bx
dx,cs:winpos
dx,1
cs:winpos,dx
cs:winfunc
di,cs:granmask
di
dx
bx
mov
mov
mov
ax,seg stk
ss,ax
sp,200h
; seteaz stiva
call
GetVESA
mov
mov
int
ax,4f02h
bx,0101h
10h
;
; modul VESA 101h (640x480, 256 culori)
;
mov
mov
ax,0a000h
ds,ax
endm
703
mov
mov
mov
mov
mov
call
eax,10h
ebx,13h
ecx,20bh
edx,1a1h
ebp,21h
Lin
mov
int
ax,4c00h
21h
; afieaz linie
GetVESA
proc
; se iniializeaz variabile n funcie de granularitatea ferestrei
mov
ax,4f01h
mov
cx,0101h
lea
di,buff
; folosim rutina VESA pentru
push cs
; a regsi parametrii modului 101h
pop
es
int
10h
add
di,4
mov
ax,word ptr es:[di] ;granularitatea ferestrei (n KB)
shl
ax,0ah
dec
ax
mov
cs:granmask,ax
; = granularitatea - 1 (n Bytes)
not
ax
clc
GVL1:
inc
cs:bitshift
rcl
ax,1
jc
GVL1
add
cs:bitshift,0fh
inc
ax
mov
disp64k,ax
add
di,8
mov
eax,dword ptr es:[di]
; adresa ferestri de control
mov
cs:winfunc,eax
ret
buff
label byte
db
100h dup (?)
endp
Lin
proc
; Date de intrare: eax: x1, ebx: y1, cx: x2, dx: y2, bp: culoare
; Modific: ax, bx, cx, edx, si, edi
; Folosete:
;
winfunc(dd),winpos(dw),page(dw),granmask(dw),disp64k(dw),bitshift(d
b)
; eax, ebx trebuie s aib cuvintele semnificative setate pe 0
cmp
ja
dx,bx
LinS1
; sortare vrfuri
704
xchg
xchg
ax,cx
bx,dx
LinS1:
sub
ja
neg
xor
cx,ax
LinS2
cx
cs:xinc1[1],28h
LinS2:
sub
neg
dec
dx,bx
dx
dx
; calcul delta_x
; modific bucla intern dup semn
;delta_y
shl
add
lea
bx,7
ax,bx
edi,[eax][ebx*4]
mov
xor
mov
shl
add
mul
push
mov
shld
pop
add
and
mov
call
mov
si,dx
bx,bx
ax,cs:page
ax,2
; pageOffset=page*5*disp64K
ax,cs:page
cs:disp64k
cx
; iniializeaz fereastr CPU
cl,cs:bitshift
; la punctul superior al liniei
edx,edi,cl
cx
dx,ax
di,cs:granmask
cs:winpos,dx
cs:winfunc
dx,si
mov
mov
ax,bp
bx,dx
[di],al
bx,cx
LinS3
di,280h
LinR2
dx
LinL1
LinOut
[di],al
; rutina de desenare
705
xinc1
LinS3:
add
jc
LinE2:
add
jns
jmp
label byte
; trecerea la urmtorul pixel pe
; orizontal
di,1
LinR1
bx,si
LinL2
LinE1
LinR1:
js
LinS7
PgDown
mov
ax,bp
jmp
LinE2
LinS7:
PgUp
mov
ax,bp
jmp
LinE2
LinR2:
PgDown
mov
ax,bp
inc
dx
jnz
LinL1
LinOut:
mov
ret
endp
cs:xinc1[1],0c7h
winfunc
winpos
granmask
ferestrei
disp64k
page
video)
bitshift
a
ends
stk
dd
dw
dw
?
?
?
dw
dw
?
0
db
1MB
ends
end
22.5 Concluzii
Acest capitol ofer informaii introductive i exemple n domeniul
programrii grafice folosind limbajul de asamblare. Trebuie precizat faptul c toate
aceste exemple ruleaz numai sub sistemul de operare DOS.
706
23
PROGRAME REZIDENTE
23.1 Caracteristicile programelor rezidente
Pe microcalculatoarele care folosesc sistemul de operare DOS, la un
moment dat poate rula un singur program. Acesta ocup memorie RAM i deine
controlul sistemului de calcul. La ncheierea sa, memoria ocupat este eliberat i
sistemul de operare DOS preia controlul. Exist ns posibilitatea de a realiza
programe care odat ncheiate s rmn n memorie, dnd totodat posibilitatea
altor programe s ruleze n spaiul de memorie rmas liber. Ele pot fi activate de
anumite evenimente externe sau interne sau pot fi activate de ctre un alt program
ce este activ n memorie, n acel moment. Aceste programe se numesc programe
rezidente sau programe TSR (Terminate and Stay Resident).
Bryan Pfaffenberger n Dicionar explicativ de calculatoare definete
programul rezident ca fiind un program accesoriu sau utilitar realizat pentru a
rmne n memoria cu acces aleatoriu (RAM) n permanen, astfel c poate fi
activat cu o comand, chiar dac mai este un alt program n memorie.
Programele rezidente pot fi folosite n operaii de monitorizare a sistemului.
n acest caz programul poate fi activat la intervale de timp stabilite pentru a verifica
starea sistemului sau este activat de evenimente cum sunt solicitrile de resurse,
avnd astfel posibilitatea de a msura diferii parametri sau de a impune un control
suplimentar la acordarea de resurse aplicaiei solicitante. n acest sens se
implementeaz sisteme de securitate care s permit accesul la anumite resurse
doar a persoanelor sau aplicaiilor autorizate. Un exemplu din aceast categorie l
707
Hardware
Interne
ntreruperi
BIOS
Sistem
DOS
Software
Utilizator
708
0000:0000h
0000:0004h
0000:0008h
0000:000Ch
0000:03FCh
0000:0400h
709
710
711
712
Memoria
convenional
(640ko)
Tabela vectorilor de
ntrerupere
Zona de date BIOS
Nucleul sistemului de
operare
Zona System Data
Zona System Code
Partea rezident a
COMMAND.COM
0000:0000h
0040:0000h
Zona proceselor
tranzitorii
Memoria
superioar
(384ko)
Memoria video
BIOS video
BIOS periferice
ROM-BIOS
A000:0000h
C000:0000h
C800:0000h
F000:0000h
FFFF:000Fh
713
Offset
0
1
Lungime
1 octet
1 cuvnt
1 cuvnt
5
8
3 octei
8 octei
Tabelul 23.1.
Semnificaie
identificatorul blocului (M sau Z)
adresa de segment a PSP al
proprietarului
dimensiunea zonei de memorie
asociate (n paragrafe)
rezervat
numele proprietarului
714
adr_seg_MCBn+1=adr_seg_MCBn+dim+1
unde dim este dimensiunea n paragrafe a zonei de memorie pe care o precede
MCBn .
Adresa de segment a primului MCB din lan se afl la deplasamentul -2, n
tabela INVARS a sistemului de operare MS-DOS. Adresa acestei tabele se
determin cu ajutorul funciei DOS 52h.
Dac adresa de segment a PSP al proprietarului, care se gsete n MCB la
deplasamentul 1, este 0, atunci zona de memorie precedat de ctre acel MCB este
liber.
Dac valoarea de la deplasamentul 1 este 8, atunci avem de-a face cu o zon
sistem. n acest caz, dac la deplasamentul 8 gsim numele SD nseamn c zona
ce urmeaz acelui MCB este zona SYSTEM DATA. Dac aici gsim numele SC,
atunci este vorba de zona SYSTEM CODE.
Zona SYSTEM DATA este la rndul ei organizat pe subblocuri de
memorie, fiecare subbloc fiind precedat de ctre un MCB. Primul MCB de subbloc,
din aceast zon se afl imediat dup blocul MCB ce marcheaz ntreaga zon
SYSTEM DATA. Subblocurile acestei zone se recunosc dup identificatorul al
MCB care le precede (deplasament 0). Acest caracter poate fi:
D pentru subblocul ce aparine unui driver ncrcat printr-o
comand DEVICE din CONFIG.SYS. n acest caz, numele de la
deplasamentul 8 este chiar numele driver-ului.
F pentru subblocul OPEN FILE TABLES;
X pentru subblocul FILE CONTROL BLOCKS;
B pentru subblocul BUFFERS;
L pentru subblocul CURRENT DIRECTORIES;
S pentru subblocul STACKS.
715
716
Tabelul 23.2.
Offset
00h
02h
Lungime
1 cuvnt
1 cuvnt
04h
05h
1 octet
5 octei
0Ah
0Eh
12h
16h
2 cuvinte
2 cuvinte
2 cuvinte
1 cuvnt
18h
2Ch
20 octei
1 cuvnt
2Eh
5Ch
6Ch
80h
46 octei
36 octei
20 octei
1 octet
81h
127 octei
Semnificaie
codul unei instruciuni INT 20h
adresa de segment a vrfului
memoriei de baz ocupate
rezervat
codul unei instruciuni CALL
seg_int21h:off_int21h
adresa rutinei de tratare INT 22h
adresa rutinei de tratare INT 23h
adresa rutinei de tratare INT 24h
adresa de segment a PSP al
procesului printe
rezervat
adresa de segment a blocului de
environment
rezervat
primul FCB standard, nedeschis
al doilea FCB standard, nedeschis
lungimea irului cu parametrii
programului
parametrii programului din linia de
comand
717
718
pentru a executa un salt la locaia de memorie imediat urmtoare PSP. Acesta este
ntotdeauna punctul de intrare ntr-un program de tip COM.
Aspecte specifice ale formatului EXE
Programele executabile n format EXE folosesc orice model de memorie,
deci nu exist restricii privind numrul de segmente. De asemenea, codul, datele i
stiva se pot gsi n segmente separate, chiar mai multe pentru fiecare n parte, sau
se pot combina ntre ele. ntr-un astfel de program coexist att apeluri de tip
NEAR, ct i apeluri de tip FAR. Aceasta face ca programele de tip EXE s fie
dependente de locul unde se ncarc n memorie, adic vor exista n program
simboluri a cror valoare depinde de adresa de segment ncepnd de la care se
ncarc programul. De aceea este nevoie ca la ncrcarea acestor programe n
memorie s se fac o operaie de relocare, adic de recalculare a acelor valori
dependente de adresa de segment ncepnd de la care se face ncrcarea
programului n memorie.
Punctul de intrare n program nu mai este fix, el putndu-se gsi oriunde
dorete programatorul, care precizeaz acest punct n cadrul directivei END.
Dei programul se ncarc tot imediat dup PSP propriu, acesta nu mai este
inclus n nici unul din segmentele programului i de aceea, la scrierea programului
nu mai este nevoie s se precizeze locul pe care l va ocupa PSP.
Fiierul ce conine un program n format EXE conine pe lng imaginea
programului n memorie, mai puin PSP i un header ce conine o serie de
informaii necesare la ncrcarea i lansarea n execuie a programului. Acest
header are urmtoarea structur:
719
Tabelul 23.3.
Offset
00h
02h
Lungime
2 octei
1 cuvnt
04h
1 cuvnt
06h
1 cuvnt
08h
1 cuvnt
0Ah
1 cuvnt
0Ch
1 cuvnt
0Eh
1 cuvnt
10h
1 cuvnt
12h
14h
16h
1 cuvnt
1 cuvnt
1 cuvnt
18h
1Ah
1 cuvnt
1 cuvnt
TablOff
2*ReloCnt
cuvinte
? octei
Semnificaie
MZ (semntura fiierelor .EXE)
PartPag = lungime fiier modulo
512
PageCnt = lungime fiier n pagini
de 512 octei
ReloCnt = numr de elemente din
tabela de relocare
HdrSize = dimensiune header n
paragrafe de 16 octei
MinMem = necesar minim de
memorie dup sfritul programului
(n paragrafe)
MaxMem = necesar maxim de
memorie dup sfritul programului
(n paragrafe)
ReloSS = deplasament segment
stiv
ExeSP = offset vrf stiv la
lansarea n execuie
ChkSum = sum de control
ExeIP = offset adres de start
ReloCS = deplasament segment de
cod
TablOff = offset tabel de relocare
indicator de overlay (0 pentru
modulele de baz)
tabela de relocare
caractere pn la limita de paragraf
720
721
fie prin funcia DOS 31h. Aceast funcie menine rezervat prima parte a zonei de
memorie ocupat de program, parte a crei dimensiune este transmis rutinei de
tratare a ntreruperii apelate. Zona de memorie imediat urmtoare prii marcate ca
rezident este eliberat i apoi controlul este redat sistemului de operare sau
programului ce a lansat n execuie programul rezident, dac exist un astfel de
program.
Orice program rezident este constituit din dou mari pri: o parte rezident
i o parte nerezident. Partea nerezident trebuie s fie plasat n program dup
partea rezident, deoarece funcia TSR pstreaz n memorie partea de nceput a
programului i elibereaz memoria ocupat de partea final a programului.
0
P.S.P.
100h
jmp etichet_nerezident
Date modul rezident
Rutine de tratare a
ntreruperilor
int_x1:
int_x2:
............
etichet_nerezident:
Bloc decizie
instalare/dezinstalare/alte
operaii
Date modul nerezident
Modul de instalare
apel funcie TSR
Modul de dezinstalare
722
723
724
725
726
727
728
729
prompter. Ceea ce nseamn c mai mereu aceast funcie este activ. Pentru a
rezolva aceast problem, sistemul de operare MS-DOS pune la dispoziie
ntreruperea INT 28h pe care sistemul o apeleaz de fiecare dat cnd se afl n
ateptare (de exemplu cnd interpretorul COMMAND ateapt introducerea unei
comenzi).
Aceast ntrerupere indic faptul c programele rezidente se pot activa n
siguran. Rutina original a ntreruperii execut un simplu IRET. Programele
rezidente pot intercepta aceast ntrerupere pentru a se activa la apelul ei. Pe
parcursul tratrii acestei ntreruperi pot fi apelate n siguran toate funciile DOS al
cror numr este mai mare dect 0Ch, cu meniunea c funciile DOS 3Fh i 40h nu
trebuie s foloseasc un handler ce refer dispozitivul CON.
Interdicia ntreruperii activitilor critice n timp
Programelor rezidente le este interzis s se activeze n timp ce se execut o
rutin critic din punct de vedere al timpului de execuie. Dac nu se respect
aceast interdicie, atunci datorit interveniei programului rezident vor apare
ntrzieri n execuia rutinei critice, deci desincronizri n lucrul cu perifericul la
care se refer rutina i ca urmare pot apare pierderi de date.
Pentru a preveni acest lucru, programul rezident va trebui s intercepteze
toate rutinele critice n timp i s execute urmtoarele operaii n noua rutin:
setare indicator de execuie rutin critic n timp;
apel rutin original;
resetare indicator de execuie rutin critic n timp.
n felul acesta, pe parcursul execuiei rutinei critice, programul rezident va
avea un indicator propriu setat corespunztor i care i va spune c nu se poate
activa. Deci, la orice tentativ de activare, programul rezident va trebui s verifice
mai nti situaia acestui indicator.
Interdicia ntreruperii tratrii erorilor critice
Programele rezidente nu trebuie s ntrerup rutina care trateaz o eroare
critic pentru a nu provoca modificarea codului de eroare i a nu afecta astfel
execuia programului ntrerupt. Pentru a ti cnd are loc tratarea unei erori critice,
programul rezident poate testa un indicator a crui adres se obine cu ajutorul
funciei DOS 5Dh, subfuncia 6.
Indicatorul de eroare critic se reprezint pe un cuvnt i este diferit de 0
dac este n curs de tratare o eroare critic.
La instalarea programului rezident se va apela funcia DOS 5Dh, subfuncia
6h i se va memora adresa coninut n DS:SI la o locaie din modulul rezident. n
felul acesta se va evita apelarea funciei DOS de ctre rutina de tratare a ntreruperii
interceptate. La apariia unei tentative de activare a programului rezident, se va
730
731
732
733
sp_int dw ?
;SP al programului intrerupt
ss_int dw ?
;SS al programului intrerupt
sp_int2 dw ?
;SP al TSR-ului
stiva dw 64 dup(?)
;stiva TSR-ului
varf_stiva label word
int_8:
;codul
int_10h:
;codul
int_13h:
;codul
int_88h:
;codul
nerezident:
;modulul nerezident
734
int13h:
;rutina de tratare a INT 13h
mov cs:inbios,1
pushf
call cs:int13h_veche
mov cs:inbios,0
retf 2
735
736
737
det_cifre
mov
div
add
mov
add
mov
endm
macro cifra_ofs
;;det. cifrele sec., min. sau orelor
cl,10
cl
;;impart nr. la 10 (se afla in AX)
ah,'0'
;;fac conversia la ASCII
cs:ceascifra_ofs+2,ah
;;in AH se afla cifra unitatilor
al,'0'
;;fac conversia la ASCII
cs:ceascifra_ofs,al ;;in AL se afla cifra zecilor
738
rezident dac acesta este instalat, respectiv din cadrul adresei de segment a
programului curent. Dac irurile sunt identice, atunci programul este deja instalat
i se apeleaz modulul de dezinstalare, iar dac irurile difer, atunci programul nu
a fost instalat i se apeleaz modulul de instalare:
mov ax,cs
mov ds,ax
mov ax,3588h
int 21h
;ES:BX=adresa rutina INT 88h
mov di,offset semnatura
mov si,di
;DI si SI = offset semnatura
cld
mov cx,lung_sem
repe cmpsb
;compar sirurile DS:SI si ES:DI
jne instalare ;daca diferite, instalare
jmp dezinstalare ;daca identice, dezinstalare
739
cx,es
ax,3508h
21h
ax,es
cx,ax
nu_posibil
ax,3510h
21h
ax,es
cx,ax
nu_posibil
ax,3513h
21h
ax,es
cx,ax
nu_posibil
ds,es:int8_veche_seg
dx,es:int8_veche_off
ax,2508h
21h
;restaurare int. 8
ds,es:int10h_veche_seg
dx,es:int10h_veche_off
ax,2510h
21h
;restaurare int. 10h
ds,es:int13h_veche_seg
dx,es:int13h_veche_off
ax,2513h
21h
;restaurare int. 13h
ax,0
ds,ax
dx,0
ax,2588h
21h
;dezactivare int. 88h
ah,49h
21h
;eliberare memorie TSR
740
23.9 Concluzii
Din coninutul acestui capitol se poate constata faptul c realizarea de
programe rezidente ridic probleme deosebite fa de programele clasice. Se
remarc faptul c este necesar respectarea riguroas a unor reguli suplimentare de
programare, precum i luarea n considerare a mai multor detalii tehnice privind
sistemul de calcul i sistemul de operare. n felul acesta programatorul are mai
puin libertate de aciune, iar programul rezultat este mult mai strns legat de
mediul de operare pentru care a fost creat.
Programele rezidente sunt programe cu grad foarte redus de portabilitate.
Ele pot rula doar pe acea clas de maini pentru care au fost realizate (n cazul de
fa este vorba de maini de tip PC), ce folosesc una din versiunile sistemului de
operare DOS. De asemenea, ele funcioneaz doar n modul real al procesorului,
specific pentru funcionarea sistemului de operare DOS. Mai mult dect att, este
posibil ca domeniul de funcionalitate al unui anumit program rezident s fie i mai
restrns dac acesta se folosete de caracteristici particulare ale unei anumite
versiuni de sistem de operare sau de detalii tehnice specifice unei anumite maini.
O alt meniune ce trebuie fcut este aceea c nu orice program rezident
funcioneaz n bune condiii, concomitent cu oricare alt program, fie el rezident
sau nu. Acest lucru se datoreaz faptului c sistemul de operare DOS este
monotasking i nu a fost prevzut s trateze conflictele ce pot apare ntre dou
procese active, care solicit aceleai resurse. Conflictele apar, de regul, ntre un
program rezident i un alt program, rezident sau nu, care se folosete de anumite
particulariti tehnice, ocolind interfaa standard oferit de sistemul de ntreruperi.
La realizarea programelor rezidente este nevoie s se acorde o mai mare
atenie optimizrii codului, deoarece, pe de o parte, un program rezident trebuie s
ocupe un minimum de memorie intern, iar pe de alt parte, rutinele programului
rezident trebuie s aib timpi minimi de execuie pentru a nu ncrca prea mult
procesorul cu operaii suplimentare. Aceast problem se pune cu att mai mult
atunci cnd programul rezident intervine asupra unor rutine critice ale sistemului.
Efortul suplimentar depus n realizarea programelor rezidente este justificat
deoarece aceste programe ofer o mbuntire a utilizrii unor programe cu
frecven mare de utilizare, n condiii de utilizare redus a resurselor
calculatorului, precum i posibilitatea de a realiza lucruri imposibil sau foarte
dificil de obinut cu ajutorul programelor clasice.
24
741
742
subseturi ai acestora. Civa regitri sunt accesai direct prin nume, ceilali fiind
setai i citii prin instruciuni specifice. n continuare sunt reluate unele elemente
privind resursele sistemelor de calcul (regitri, indicatori de stare) dar n contextul
lucrului protejat.
Regitrii de segment
Adresele de segment ale modului real i selectorul de segment din modul
protejat sunt stocate n 6 regitri pe 16 bii. Registrul selector de segment este
folosit n modul protejat pentru a selecta descriptorul de segment definit n tabela
descriptorilor.
15
CS
DS
ES
SS
FS
GS
Regitrii de uz general
Regitrii de uz general pe 32 de bii sunt numii EAX, EBX, ECX, EDX,
ESI, EDI, EBP i ESP. Primii 16 bii ai lor pot fi accesai sub numele de AX, BX,
CX, DX, SI, DI, BP, i respectiv SP i sunt folosii de ctre programele pe 16 bii
pentru procesoarele din generaiile inferioare. Octeii regitrilor AX, BX, CX, DX
743
pot fi referii ca AH, AL, BH, BL, CH, CL, DH i respectiv DL. Aceti regitri sunt
folosii pentru manipularea datelor n instruciuni.
31
16
15
8
AH
BH
CH
DH
SI
DI
BP
SP
IP
EAX
EBX
ECX
EDX
ESI
EDI
EBP
ESP
EIP
A
B
C
D
X
X
X
X
AL
BL
CL
DL
Registrul EFLAGS
Reprezint extinderea pe 32 de bit a registrului FLAGS de la procesoarele
8086, primii 12 bii avnd aceeai funcie ca la procesoarele pe 16 bii.
31
Rezervat
17
V
16 15
R
0 N IO
O D
7
I T S Z
F F
F F F F
T PL
A 0
0
1 C
31
Rezervat
18 17 16
A V R
T PL F
IO O D I
F
7
S
A 0 P
F
0
C
F
744
Regitrii de control
Procesoarele i386/i486 au trei regitri de control: CR0, CR2 i CR3,
registrul CR1 este rezervat pentru utilizri viitoare. Aceti trei regitri stocheaz
starea global sau controlul operaiilor procesoarelor i386/i486.
Formatul registrului de control al mainii (CR0) este dat n figura 24.5
31
PG
4
ET
Rezervat
3
TS
2
EM
1
0
MP PE
31
PG
30
CD
29
NW
18
AM
16
WP
5
NE
4
ET
3
TS
2
EM
1
0
MP PE
745
746
Base Register
Limit Register
TR (selector)
Base Register
Limit Register
16
15
0
Reserved
LDT
GS
FS
64
60
5C
58
747
Reserved
Reserved
Reserved
Reserved
EDI
ESI
EBP
ESP
EBX
EDX
ECX
EAX
EFLAGS
EIP
CR3
Reserved
ESP2
Reserved
ESP1
Reserved
ESP0
Reserved
DS
SS
CS
ES
SS2
SS1
SS0
Back link to previous TSS
54
50
4C
48
44
40
3C
38
34
30
2C
28
24
20
1C
18
14
10
0C
8
4
0
Base
G B 0 V Limit
P DPL 1 0 E W A Base
31..24
19..16
23..16
Segment Base 15..0
Segment Limit 15..0
G Granulaia
B Segment mare
V Disponibil pentru utilizare
P Existena segmentului
DPL Nivelul de prioritate al
E Expandare
descriptorului
A Accesat
W Permite scriere
Figura 24.9 Formatul descriptorului segmentului de date
Base
G D 0 V Limit
31..24
19..16
Segment Base 15..0
P DPL 1 1 C
Segment Limit 15..0
R A
Base
4
23..16
0
4
0
748
D dimensiunea
operaiilor
implicit
R permite citirea
C bit de conformitate
P DPL 0 0 1 0
Segment Limit 15..0
Rezervat
4
0
P DPL 0 X 1 0 0 0 0 0 Count
Segment Limit 15..0
4
0
P DPL 0 X 1 1 1 T 0 0 Rezerved
Segment Limit 15..0
4
0
P DPL 0 0 0
Base
23..16
4
0
Base
G 0 0 V Limit
31..24
19..16
Segment Base 15..0
P DPL 0 X 0
B 1
Base
23..16
4
0
Instruciuni
Procesoarele i486 suport toate instruciunile procesorului i386, punnd la
dispoziie nc ase instruciuni.
Instruciuni utilizator
Instruciuni de sistem
Mecanismul de segmentare
Segmentarea ofer o modalitate simpl dar nestructurat de gestiune a
memoriei. Un program poate avea cteva spaii de adres protejate independente.
Un segment este un bloc de memorie a crei dimensiune este variabil.
Dimensiunea segmentelor folosite de ctre un program poate fi orict de mare, cu
condiia s nu depeasc memoria total disponibil n sistem. nainte de a accesa
2
TI
1 0
RPL
TI indicator de tabel
RPL (Requested Privilege Level) nivelul de prioritate solicitat
Figura 24.15 Selectorul de segment
Dac TI = 0 descriptorul se selecteaz din GDT, dac TI = 1 descriptorul se
selecteaz din LDT.
Paginarea
Spre deosebire de segmentare, paginarea mparte memoria sistemului n
blocuri de memorie de dimensiune fix, fiecare bloc fiind numit pagin. Pe
sistemele i386/i486, o pagin ocupa 4Kb. O adres liniar, obinut prin
10
11
dw
dw
db
db
db
db
0ffffh
?
?
9ah
0
0
;limita(0-15)
;adresa de baza(0-15)
;adresa de baza(16-23)
;present=1,readable=1
;limit
a(16-19), G=0, D=0
;baza(24-31)
dw
dw
db
db
db
db
0ffffh
?
?
92h
0
0
;limita(0-15)
;adresa de baza(0-15)
;adresa de baza(16-23)
;present=1, writable=1
;limita(16-19), G=0, D=0
;baza(24-31)
;selector fictiv
;resetarea registrilor de segment
12
mov
mov
mov
cli
mov
and
mov
db
dw
dw
read_mode:
mov
mov
lidt
fs,ax
gs,ax
ss,ax
;dezactivarea intreruperilor
eax,cr0
eax,not prot_enable ;dezactivarea modului protejat
cr0,eax
0eah
;salt neconditionat
offset real_mode ;EIP
code
;CS
ax,data
ds,ax
[oldidt]
;reincarcarea tabelei de
;intreruperi pentru modul real
;reactivarea intreruperilor
sti
Exemplu
Urmtorul exemplu demonstreaz comutarea ntre mod real i modul
protejat. Acest program pregtete structurile de date de baz pentru intrarea n
modul protejat. Programul nu include paginare, multitasking sau protecie n modul
protejat.
n cadrul acestui program se folosesc dou fiiere incluse:
STRUCT definete majoritatea structurilor de date folosite n modul
protejat
MACRO1 definete cteva macrodefiniii folosite n programul
principal.
Fiierul STRUCT:
;Structura descriptorului de segment
dscp
dscp
struct
D_lim1
D_base1
D_base2
D_type
D_lim2
D_base3
ends
db
dw
dw
db
db
db
0
0
0
0
0
0
struct
dw
dw
0
13
oldcs
dw
dw
oldflg
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
ends
oldsp
oldss
oldes
oldds
oldfs
oldgs
stkdef
0
0
dw
0
0
0
0
0
0
0
0
0
0
0
0
0
?
?
?
Fiierul MACRO1
;Macrodefinitie pentru definirea stivei n TSS
TSS_stack
dd
dd
dd
dd
dd
dd
dd
endm
macro ss0,esp0,ss1,esp1,ss2,esp2
0
offset esp0
ss0
offset esp1
ss1
offset esp2
ss2
macro
0
14
dd
dd
dd
dd
dd
dd
dd
dd
teax
tecx
tedx
tebx
offset tesp
tebp
tesi
tedi
endm
;Macrodefinitie pentru definirea registrilor de segment n TSS
TSS_seg
dd
dd
dd
dd
dd
dd
endm
macro tes,tcs,tss,tds,tfs,tgs
tes
tcs
tss
tds
tfs
tgs
selector
9ah
0
selector
Program: EN.ASM
Acest program demonstreaz trecerea din modul real al sistemului de
operare DOS n modul protejat i rentoarcerea din modul protejat n modul real
DOS. Programul seteaz, mai nti, structurile de date ale modului protejat (GDT,
IDT i TSS) apoi intr n modul protejat, unde afieaz un mesaj, dup care
prsete modul protejat i restaureaz contextul modului real. Paii de execuie ai
programului sunt:
Pasul 0:
Definirea EQU.
Pasul 1:
Tabela descriptorilor locali nu este folosit n acest program, astfel nct toi
descriptorii sunt definii n tabela descriptorilor globali. n aceast tabel se
definete doar dimensiunea i tipul fiecrui descriptor, adresa de baz urmnd a fi
setat la momentul execuiei.
15
Pasul 2:
Definirea variabilelor.
Pasul 4:
Definirea tabelei de mapare pentru fiecare selector ctre
segmentul corespunztor.
Aceast tabel conine acei selectori pentru care adresa de baz trebuie
iniializat n descriptor. Segmentul corespunztor este definit folosind selectorul
asociat.
gdt_tab-size conine numrul de intrri ale tabelei GDT.
Pasul 5:
Definirea mesajelor.
Pasul 6:
Pasul 7:
Setarea TSS.
Pasul 8:
Definirea unui segment fictiv folosit pentru obinerea valorii
registrului descriptor de segment la ntoarcerea n modul real.
Pasul 9:
Iniializarea punctului de intrare pentru fiecare descriptor de
ntrerupere definit n IDT. Pentru fiecare rutin de ntrerupere se rezerv 4 octei
ntr-un vector n memorie.
16
Pasul 13: Seteaz regitrii LDTR, SS, SP, DS, ES, FS i GS.
Pasul 14: Afieaz mesajul pe ecran.
Datorit faptului c funciile de sistem DOS nu sunt disponibile n modul
protejat, programul scrie mesajul direct n memoria video, n secvena:
scrie spaii n memoria video pentru a terge ecranul
afieaz mesajul
Pasul 15: ncarc selectorul segmentului procesului curent n registrul
proceselor (TS)
Pasul 16: Apeleaz o ntrerupere software prin intermediul descriptorilor de
ntreruperi definii n IDT. Rutina ntreruperii afieaz numrul ntreruperii i
comut napoi n modul real DOS.
Fiierul EN.ASM
.386p
include struct
include macro1
;Pasul 0: definire EQU
INTNO
DSCPSIZE
INTSIZE
TWO
prot_enable
equ
equ
equ
equ
equ
21
8
4
2
01h
17
attribute
space
equ
equ
;Pasul 1:
GDT
07h
20h
equ
$-gdt_tab
<,,,,,>
code_selec
equ $-gdt_tab
dscp
<0ffffh,,,09h,,>
use16
GDT
;descriptorul selectorul
;segmentului de
;cod
task0_TSS_selec
equ
$-gdt_tab
;descriptorul selectorului
dscp
<task0_TSS_limit,,,089h,,>
;segmentului TSS
stk0_selec
dscp
0
equ
$-gdt_tab
<stk0_limit,,,92h,,>
;descriptorul selectorului
;segmentului de stiva de nivel
stk1_selec
dscp
equ
$-gdt_tab or 1
<stk1_limit,,,0b2h,,>
;descriptorul selectorului
;segmentului de stiva de
;nivel 1
stk2_selec
dscp
equ
$-gdt_tab or 2
<stk2_limit,,,0d2h,,>
;descriptorul selectorului
;segmentului de stiva de
;nivel 2
dmy_selec
dscp
equ
$-gdt_tab
<0ffffh,,,92h,,>
video_selec equ
$-gdt_tab or 3
dscp
<0ffffh,8000h,0bh,0f2h,,>
gdata_selec equ
$-gdt_tab
dscp
<gdata_limit,,,0f2h,,>
int_selec
dscp
equ
$-gdt_tab
<0ffffh,,,09ah,,>
gdt_limit
GDT
ends
equ
;Pasul 2:
IDT
$-gdt_tab
IDT
segment para
public use 16 idt
idt_tab
equ
$
REPT INTNO
dscop <,int_selec,0,0eeh,,>
ENDM
18
idt_limit
IDT
ends
equ
;Segmentul de date
Gdata segment para public use16 Gdata
;Pasul 3:
Definirea variabilelor
pGDT
pGDT_limit
pGDT_addr
label fword
dw
?
dd
?
pIDT
pIDT_limit
pIDT_addr
label fword
dw
?
dd
?
pold
dIDT_limit
dIDT_addr
label fword
dw
03ffh
dd
0
;Pasul 4:
gdt_phys_tab
label word
dw
task0_TSS_selec
dw
task0_TSS
dw
stk0_selec
dw
stk0
dw
stk1_selec
dw
stk1
dw
stk2_selec
dw
stk2
dw
dmy_selec
dw
dmy
dw
code_selec
dw
code
dw
gdata_selec
dw
gdata
dw
int_selec
dw
code
gdt_tab_size
equ
($ - gdt_phys_tab) / 4
;Pasul 5:
Definirea mesajelor
in_protected
int_msg
int_num
Gdata_limit equ
Gdata ends
db
dw
db
$
db
MOD PROTEJAT,0
Intreruperea:
?
H,0
19
;Pasul 6:
stk0
segment
para public use16 stk0
db
100h dup(0)
stk0_limit equ $
stk0 ends
stk1
segment
para public use16 stk1
db
100h dup(0)
stk1_limit equ $
stk1 ends
stk2
segment
para public use16 stk2
db
100h dup(0)
stk2_limit equ $
stk2 ends
;Pasul 7:
TSS
task0_TSS
TSS_stack
segment
para public use16 task0
stk0_selec,stk0_limit,stk1_selec,
stk1_limit,stk2_selec,stk2_limit
TSS_cr3
0
TSS_regs
0,0,0,0,0,0,0,0,0,stk0_limit
TSS_seg
gdata_selec,code_selec,stk0_selec,
gdata_selec,gdata_selec,gdata_selec
dd
0
;LDT
dw
0
;task trap flag
dw
68h
;adresa de I/O
task0_TSS_limit
equ
$
task0_TSS
ends
;Pasul 8:
dmy
dmy
Segmentul fictiv
segment
db
128
ends
para public
dup(0)
use16 dmy
;Segmentul de cod
code segment
assume
main
proc
mov
mov
;Pasul 9:
mov
mov
mov
far
ax,gdata
ds,ax
Initializarea IDT
ax,IDT
es,ax
di,offset
idt_tab
20
mov
ax,offset
int_entry
mov
fillidt:
mov
add
axx
loop
cx,INTNO
;Pasul 10:
es:[di],ax
di,DSCPSIZE
ax,INTSIZE
fillidt
mov
mov
xor
mov
shl
ax,offset
gdt_kimit
pGDT_limit,ax
eax,eax
ax,GDT
eax,4
mov
pGDT_addr,eax
mov
mov
xor
mov
shl
ax,offset
idt_limit
pIDT_limit,ax
eax.eax
ax,idt
eax,4
mov
pIDT_addr,eax
ax,GDT
es,ax
si,offset gdt_phys_tab
mov
cx,gdt_tab_size
bdt1:
lodsw
mov
bx,ax
and
bx,0fff8h
lodsw
push
shl
mov
ax
ax,4
es:[bx][d_base1],ax
pop
shr
mov
ax
ax,12
es:[bx],d_base2],al
loop
bdt1
21
cli
lgdt
lidt
[pGDT]
[pIDT]
mov
or
mov
eax,cr0
al,prot_enable
cr0,eax
jmp
dword ptr
cs:[enter_prot]
enter_prot:
dw
offset
dw
code_selec
now_in_prot
ax,ax
ax
ax,stk0_selec
ss,ax
sp,offset stk0_limit
ax,gdata_selec
ds,ax
es,ax
fs,ax
gs,ax
mov
mov
mov
xor
mov
mov
rep
mov
ax,video_selec
es,ax
cx,4000h
di,di
ah,attribute
al,space
stosw
si,offset
in_protected
mov
call
di,320
disp_it
;Pasul 15:
mov
ltr
22
;Pasul 16:
int
int_entry:
REPT
call
iret
ENDM
INTNO
disp
disp:
pop
mov
mov
sub
ax
bx,gdata_selec
ds,bx
ax,offset
int_entry
shr
mov
mov
call
mov
mov
call
ax,TWO
si,offset
cx,TWO
htoa
si,offset
di,5*160
disp_it
cli
mov
mov
mov
mov
mov
mov
mov
and
mov
ax,dmy_selec
es,ax
ds,ax
fs,ax
gs,ax
ss,ax
eax,cr0
eax,not
prot_enable
cr0,eax
db
dw
dw
0eah
offset
code
next_instruction:
mov
ax,Gdata
mov
ds,ax
mov
ax,stk0
mov
ss,ax
mov
sp,offset
lidt
[pold]
sti
mov
ax,4c00h
int_num
int_msg
next_instruction
stk0_limit
23
main
int
endp
21h
disp_it
mov
mov
mov
disp_itl:
lodsb
stosw
cmp
jne
ret
disp_it
proc near
ax,video_selec
es,ax
ah,attribute
htoa_tab
htoa proc
xor
add
dec
htoal:
mov
and
mov
db
0123456789ABCDEF
near
ebx,ebx
si,cx
si
htoa
mov
dec
shr
loop
ret
endp
code
ends
al,0
disp_itl
endp
bl,al
bl,0fh
bl,cs:[htoa_tab][ebx]
byte ptr
esi
eax,4
htoal
[esi],bl
end main
24
segment TSS poate fi stocat doar n GDT. Dac este invocat o comutare ctre un
proces al crui descriptor este stocat n LDT, procesorul genereaz o excepie.
Dac a fost invocat o comutare prin intermediul unei instruciuni CALL sau
INT, ntoarcerea ctre procesul iniial se realizeaz printr-o instruciune IRET.
Exemplul care urmeaz realizeaz comutarea ntre dou procese numite:
task0 i task1 folosind o instruciune JMP ctre descriptorul TSS al procesului
task1. Dup ce se realizeaz comutarea, procesul task1 realizeaz ntoarcerea
ctre procesul task0 folosind o ntrerupere software. Aceast ntrerupere are
descriptorul definit n IDT fiind ceea ce se numete un descriptor de tip task gate
ctre descriptorul TSS al procesului task0.
Program: mult.asm
Mai nti se definesc cele dou procese:
TSS0
dd
dd
dd
dd
dd
dd
dd
dd
dd
dd
TSS0_limit
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
equ
$
;
;esp0,ss0
;esp1,ss1
;esp2,ss2
;cr3
;eip
;eflags
;eax,ecx,ebx,edx,esp,ebp,esi,edi
;es,cs,ss,ds,fs,gs
;LDT
TSS1
dd
0
dd
task1_esp0,task1_ss0
;esp0,ss0
dd
task1_esp1,task1_ss1
;esp1,ss1
dd
task1_esp2,task1_ss2
;esp2,ss2
dd
0
;cr3
dd
task1_eip
;eip
dd
task1_eflags
;eflags
dd
task1_eax,task1_ecx,task1_ebx,task1_edx
;eax,ecx,ebx,edx
dd
task1_esp,task1_ebp,task1_esi,task1_edi
;esp,ebp,esi,edi
dd
task1_es,task1_cs,task1_ss,task1_ds
;es,cs,ss
dd
task1_ds,task1_fs,task1_gs
;ds,fs,gs
dd
0
TSS1_limit equ
$
25
db
db
db
db
TSS0_base2
89h
0
0
task1_TSS_selec
label word
dw
TSS1_limit
dw
TSS1_base1
db
TSS1_base2
db
89h
db
0
db
0
Pasul 2.1
Definirea descriptorului task gate n IDT, punctnd ctre
TSS-ul procesului task0:
dscp
<,task0_TSS_selec,0,0e5h,,>
Pasul 4.1
;intreruperea 21
task1
dw
task1_TSS_selec
dw
task1_TSS
dw
task1_code_selec
dw
task1_seg
Pasul 7.1
task1_TSS
TSS_stack
TSS_cr3
TSS_regs
TSS_seg
26
task1_TSS_limit
task1_TSS
dw
equ
ends
68h
$
Pasul 15.1
Comutarea ctre procesul task1 prin salt necondiionat
ctre selectorul segmentului TSS al procesului task1
jmpf
Pasul 17:
task1_TSS_selec
task1_seg
segment
para public use16 task1_seg
assume
cs:task1_seg,ds:gdata
task1_entry proc near
mov
si,offset task1_msg
mov
di,160*3
call disp2
int21
task1_entry endp
disp2 proc
mov
mov
mov
disp21:
lodsb
stosw
cmp
jne
ret
disp2 endp
near
ax,video_selec
es,ax
ah,attribute
al,0
disp21
task1_seg_limit
task1_seg
ends
equ
24.6 Concluzii
Spre deosebire de modul real, modul protejat ofer programatorului ntreaga
capacitate a procesoarelor i386/i486. n modul protejat multitasking-ul, memoria
virtual i protejarea spaiului alocat unui program fiind asigurate n mod nativ,
prin hardware.
n contextul tendinei de pe piaa software-ului ctre aplicaii care necesit
un volum tot mai mare de resurse, precum i datorit existenei sistemelor de
operare care lucreaz n mod protejat (sistemele MS Windows) cunoaterea
principiilor de programare n acest mod este obligatorie pentru realizarea de
programe performante sub aceste platforme.
27
25
PROGRAMAREA APLICAIILOR WINDOWS N
LIMBAJ DE ASAMBLARE
25.1 Interfaa de programare a aplicaiilor Windows
API (Application Programming Interface) pentru sistemele Win32 este
implementat n biblioteci cu legare dinamic.. Aceste biblioteci sunt separate de
programul executabil. Spre deosebire de DOS, API-urile nu sunt accesate prin
ntreruperi.
28
29
00001000H
00000FFFH
Protejata, atribuiri de pointeri NULL
Compatibilitate cu Win16
4MB
00000000H
30
31
32
33
34
35
dd
dd
dd
dd
?
?
?
?
cbWndExtra
dd ?
hInstance
dd ?
hIcon
dd ?
hCursor
hbrBackground
dd ?
dd ?
lpszMenuName
dd ?
lpszClassName
dd ?
hIconSm
dd ?
WNDCLASSEX ends
36
hinst
;...
dd
.code
;...
;completarea cimpurilor structurii fereastra
mov wcex.cbSize, size WNDCLASSEX
mov wcex.style, CS_VREDRAW or CS_HREDRAW or CS_DBLCLKS
mov wcex.lpfnWndProc, offset WndProc
mov wcex.cbClsExtra,0
mov wcex.cbWndExtra,0
push hinst
pop wcex.hInstance
;se incarca pictogtama, definita in fisierul .rc
push ID_ICON ;icon id
push hinst
call LoadIcon
mov wcex.hIcon,eax
;se incarca cursorul sageata standard
push IDC_ARROW
push NULL
call LoadCursor
mov
mov
mov
mov
mov
wcex.hCursor,eax
wcex.hbrBackground,COLOR_WINDOW+1
wcex.lpszMenuName,0
wcex.lpszClassName,offset NumeFer
wcex.hIconSm,0
37
38
);
;
;
;
;
;
;
;
;
;
;
;
;
lpParam
hInstance
identificator meniu
identificator parinte
inaltime
latime
y
x
stilul
titlul ferestrei
numele clasei
stilul extins
;...
39
BOOL ShowWindow(HWND hWnd, // identificatorul ferestrei
int nCmdShow // modul de afiare a ferestrei);
//
//
//
//
40
MSG ENDS
;
;
;
;
;
wMsgFilterMax
wMsgFilterMin
0 - toate ferestrele
lpMsg
returneaza FALSE pentru WM_QUIT
41
jz iesire
push offset msg
call TranslateMessage
push offset msg
call DispatchMessage
jmp start_bucla
// codul de ieire al
// identificatorul ferestrei
// mesajul
// primul parametru al mesajului
42
LPARAM lParam
);
Un mesaj ce trebuie tratat este WM_DESTROY care este trimis atunci cnd
utilizatorul dorete s nchid fereastra. Mesajul este tratat standard, prin apelul
funciei PostQuitMessage, ce are prototipul:
VOID PostQuitMessage(
int nExitCode
);
// codul de ieire
43
db
;Numele
db
;Numele
db
db
.data?
wcex WNDCLASSEX <?>
msg
MSG <?>
hwnd
dd ?
hinst
dd ?
hmeniu dd ?
.code
start:
;obtinerea hInstance
44
push 0
call GetModuleHandle
mov hinst,eax
;completarea campurilor structurii fereastra
mov wcex.cbSize, size WNDCLASSEX
mov wcex.style, CS_VREDRAW or CS_HREDRAW or CS_DBLCLKS
mov wcex.lpfnWndProc, offset WndProc
mov wcex.cbClsExtra,0
mov wcex.cbWndExtra,0
push hinst
pop wcex.hInstance
;se incarca iconul, definit in fisierul .rc
push ID_ICON ;icon id
push hinst
call LoadIcon
mov wcex.hIcon,eax
;se incarca cursorul sageata standard
push IDC_ARROW
push NULL
call LoadCursor
mov
mov
mov
mov
mov
wcex.hCursor,eax
wcex.hbrBackground,COLOR_WINDOW+1
wcex.lpszMenuName,0
wcex.lpszClassName,offset NumeFer
wcex.hIconSm,0
0
hinst
hmeniu
0
CW_USEDEFAULT
CW_USEDEFAULT
CW_USEDEFAULT
;
;
;
;
;
;
;
lpParam
hInstance
identificator meniu
identificator parinte
inaltime
latime
y
45
push CW_USEDEFAULT
push WS_OVERLAPPEDWINDOW
push offset NumeApp
push offset NumeFer
push WS_EX_OVERLAPPEDWINDOW
call CreateWindowEx
mov hwnd,eax
;
;
;
;
;
x
stilul
titlul ferestrei
numele clasei
stilul extins
;
;
;
;
;
wMsgFilterMax
wMsgFilterMin
0 - toate ferestrele
lpMsg
returneaza FALSE pentru WM_QUIT
46
cmp dword ptr [esp+12],ID_FISIERE_IESIRE
je msg_wm_destroy
cmp dword ptr [esp+12],ID_HELP_DESPRE
je help_despre
xor eax,eax
ret 16
msg_wm_lbuttondown:
;s-a facut click in zona client a ferestrei
;se afiseaza o casuta de dialog
;avind ca titlu NumeApp si mesaj Mesaj1
push MB_OK
push offset NumeApp
push offset Mesaj1
push NULL
call MessageBox
xor eax,eax
ret 16
help_despre:
;s-a ales optiunea Despre... din meniul Help
;se afiseaza o casuta de dialog
;avind ca titlu NumeApp si mesaj MesajDespre
push MB_OK
push offset NumeApp
push offset MesajDespre
push NULL
call MessageBox
xor eax,eax
ret 16
msg_wm_destroy:
;s-a inchis fereastra
push 0
call PostQuitMessage
xor
eax,eax
ret 16
WndProc endp
end start
47
POPUP "&Fisiere", , , 0
BEGIN
MENUITEM "&Iesire", ID_FISIERE_IESIRE
END
POPUP "&Help", , , 0
BEGIN
MENUITEM "&Despre...", ID_HELP_DESPRE
END
END
BIBLIOGRAFIE
[ABEL95] IBM PC Assembly Language and Programming 3rd Edition Prentice Hall International, Inc, New Jersey, 1995
[ATHA92] Irina Athanasiu, Alexandru Panoiu Microprocesoarele
8086, 286, 386 Editura Teora, Bucureti, 1992
[BARK90] Nabajyoti Barkakati, The Waite Group's Microsoft Macro
Assembler Bible, SAMS, Carmel Indiana, 1990
[BETH87] RWMc Beth, J. R. Ferguson, IBM Assembler John Wiley &
Sons, New York, 1987
[BREY90] Barry B. Brey, 8086/8088, 80286, 80386 and 80486
Assembly Language Programming, Macmillan Publishing
Company, New York, 1990
[BRUM88] Penn Brumm, Don Brumm, 80386 Assembly Language A
Complete Tutorial and Subroutine Library TAB Books Inc,
Blue Ridge Summit, 1988
[BUY96]
Barry Buy, Programming the 80286, 80386, 80486 and
Pentium - Based Personal, Prentice Hall Englewood Cliffs,
New Jersey, 1996
[CAPR91] Vlad Cprariu, Sisteme de operare DOS - Funcii Sistem,
Microinformatica, Ediia a III-a, Cluj Napoca, 1991
[CATO74] I. Catona, I. Teodorescu, C. Popescu, Sistemul Felix C 256, Limbajul ASSIRIS, Editura Academiei, Bucureti,
1974
[Coff87]
James W. Coffron, Programming the 8086/8088, Ed.
Kleidarifmos, Athens, 1987
48
[COHE94] Le
microprocesseur
Pentium
Architecture
et
programmation, Armand Colin, Paris, 1994
[CUOR93] Sen - Cuo Ro Shean - Chuen Her, i386/i486 Advanced
Programming, Van Nosteand Reinhold, New York, 1993
[DAVI91] A. Davidoviciu, Gh. Dodescu, coordonatori MIX i
MACRO, vol. 2, Programarea n limbajul MACRO, Editura
Tehnic, Bucureti, 1991
[DETM90] Richard C. Detmer, Fundametals of Assembly Language
Programming, PC Heath Comp., Lexington Masschusetts,
1990
[DIAC75] G. Diaconescu, I. Lungu, Assembler, Lito ASE, Bucureti,
1975
[DIMO92] Dimopoulos
K.
Z.,
Paraskevopoulos
A.S.80x86
Architictonici schediasi & Programatismos Papasotiriu Ed.
Athens, 1992
[DORF90] Len Dorfman, Object Oriented Assembly Language
Windcrest, 1990 Mc Graw Hill Inc. New York
[DORF90a] Len Dorfman, Structured Assembly Language, Windcrest
Books Blue Ridgs Summit, 1990
[DOVI91] A. DOVIDOVICIU, Gh. DODESCU Mix si Macro (vol. 2)
Programarea in limbajul MACRO Editura Tehnica,
Bucureti, 1991
[FITZ86]
Robert M. Fitz, Larry Crokett, Universal Assembly
Language, TAB Books Inc. Blue Ridge Summit PA 17214,
1986
[GHEO92] MARIAN GHEORGHE, BADICA COSTIN, PATRASCOIU
OCTAVIAN Limbaje de asamblare MACRO-11, Intel
8086/88, Lito Universitate, Craiova, 1992
[GILL94] Frame van Gilluwe, The Undocumented PC, Addison
Wesley Publishing Company Reading, 1994
[GURT89] A.L. Gurtovtev, S.V. Gudimenko Programi dlia
microprotessorov, Editura Visaisaia Scola, Minsk, 1989
[HABI88] Stanley
Habib
Microprogramming
and
firmware
engineering methods, van Nostrand Reinhold, New York,
1988
[HALL80] Douglas V. Hall, Microprocessors and interfacing
Programming and hardware, Mc. Craw Hill International
New York, 1980
[HAWK81] Gerry Kan, Danny Hawkins, Lance Leventhal 6800
Assembly Language Programming, Osborne, California,
1981
[HOLZ87] Steven Holzner, Advanced Assembly Language on the IBM
49
50
[MARI92]
[MASM78]
[MASM86]
[MAST95]
[MATS76]
[MCBE87]
[MORG84]
[MORRIS]
[MUNT76]
[MURR88]
[MUSC96]
[NORT89]
[PETZ98]
[PRET75]
[RICH94]
[RODE96]
[ROC77]
[RUNN88]
51
[SACH93]
[SALE95]
[SANC90]
[SANC94]
[SANC95]
[SCAN83]
[SCAN87]
[SCAN88]
[SCHA93]
[SCHM95]
[SENC93]
[SERA87]
[SERB85]
[SOCE75]
[SOMN92]
[STRU92]
52