Sunteți pe pagina 1din 7

6.7.

Subprograme recursive
Subprogramele normale pot apela alte subprograme, dar nu se pot apela pe ele
nsele, fie direct, fie indirect prin alte subprograme pe care le apeleaz.
Subprogramele recursive permit ca n secvena de definiie (sau n subprogramele
apelate) s se apeleze pe ele nsele. Apelul se face nainte de a se termina procedura.
Exist aplicaii care pot fi rezolvate prin algoritmi iterativi sau/i algoritmi iterativi. !a
apelarea subprogramului nu ne intereseaz ce tip de algoritm se utilizeaz. "e intereseaz ca
rezultatul obinut s fie corect.
Funcia factorial are at#t o definiie iterativ c#t i una recursiv.
Definiia iterativ este un ciclu de " nmuliri$
N! = 1**!*"*#*6*.....*N
Algoritmul iterativ ce poate fi folosit este$
F=1 F=F * $ pentru $=1....N
%efiniia recursiv se bazeaz pe valoarea funciilor anterioare care nu sunt cunoscute
N! = N*%N&1'! cunosc#nd c 1! =1( care este condiia de ieire din ciclul recursiv
&e scrie programul principal, care transmite n A' valoarea lui ", iar procedura (act
va returna n A' rezultatul ").
&*a fcut o exemplificare grafic a algoritmului pentru "+,.
!a intrarea n procedur vom gsi n stiv adresa de revenire notat -..
/n procedur se decrementeaz A' i se c0eam recursiv procedura (act.
!a fiecare -all de procedur se pune n stiv adresa de revenire -1.
-#nd A'+2 se sare la etic0eta -2 unde se initializeaz A'+2)+2 i 3'+/+2.
4rin 5E6 se revine la adresa din v#rful stivei -1 unde se face 3'+/72+. i se calculeaz .).
4rin 5E6 se revine la -1 unde se calculeaz 3'+/72+1 i A'+/8.)+1)
4rin 5E6 se revine la -1 unde se calculeaz 3'+/72+9 i A'+/81)+9)
4rin 5E6 se revine la -1 unde se calculeaz 3'+/72+, i A'+/89)+,)
)rin urmtorul *+, se revine la - .n programul principal /i 01=#!
: ****************************************************
: 4rogram recursiv pentru calcul factorial
: /ntrare A'+" /esire A'+")
:*****************************************************
)fact Segment 2co3e2
assume cs$pfact,ds$sdate,ss$stiva
st2$ mov ax,sdate : initializare registre segment
mov ds,ax
mov ax,stiva
mov ss,ax
mov sp,offset top : initializare stiva
mov ax,n : A'+" pregatire apel subprogram
call Fact : c0emare subprogram recursiv ")
2
c.$ mov f2,ax : (2+ ") memorare rezultat din A'
: int 1 : terminare program
mov ax,9c;;0
int .20
: 4rocedura recursiva calcul ")
Fact )roc near 4
dec ax <
=z c2 : "+2 si 2)+2 "< &tiva 3' A'
call Fact : apel recursiv <
c1$ inc bx : "+"72 2 < -1 2 2)
imul bx : ")+"8("*2)) . < -1 . .)
ret : revenire 1 < -1 1 1)
c2$ mov ax,2 : 2)+2 9 < -1 9 9)
mov bx,2 : "+2 &4 , < -. , ,)
ret : revenire
(act endp
4fact ends
S3ate Segment 23ata2 5 segment de date
f2 d> ;
n d> ,
&date ends
stiva Segment 2stac62 : segment de stiva
d> .,? dup(@)
top eAu B
stiva ends
end st2
%ac se transmite prin stiv i valoarea lui " la fiecare apel recursiv, atunci procedura
4(A-6 se modific, fr a modifica programul principal.
/n acest caz evoluia stivei este cea din figura urmtoare. Este o succesiune de adrese de
revenire i de valori ale lui " la c0emarea procedurii.
N Stiva 01
1 1!=1
-!
!=*1!
-!
! ! !!=!*!
-!
" " "!="*!!
-!
# N=# #!=#*#!
.
S) 03resa -
(A-6 45C-
-D4 A',2
EF GA6A : "+2 si 2)+2
4H&I A'
%E- A' : "+"*2
-A!! (A-6 : apel recursive
-1$ 4C4 3' :"+"72
/DH! 3' :") + "8("*2) )
GA6A $ 5E6
(A-6 E"%4
&e observ c dei exist un singur 5E6 efectul lui este diferit, fiindc el face un salt
la o adres din v#rful stivei, care depinde de structura stivei.
6.7. Subprograme reentrante
&ubprogramele reentrante conin cod pur care nu se modific n timpul rulrii$
/nstruciuni
-onstante, mesa=e sau tabele
"u se accept ca un subprogram reentrant s conin variabile care i modific valoarea
n timpul prelucrrii. &tarea lui nu depinde de Jinstoria saK. 4rogramul poate fi memorat ntr*o
memorie de tip 5CD (5ead CnlL DemorL).
4rincipalele caracteristici ale programelor reentrante sunt$
2. &ubprogramul reentrant poate fi folosit simultan de mai muli utilizatori.
.. El poate fi ntrerupt nainte de a se termina (ateptri de date sau ntreruperi de timp).
1. 4e perioada ntreruperii poate fi folosit de un alt utilizator, care la r#ndul lui poate fi
ntrerupt.
9. Hn program ntrerupt continu la relansare din punctul din care a fost ntrerupt.
,. (iecare utilizator va avea propria zon de memorie care are aceeai structur pentru
toi, n care sunt memorate toate variabilele din program pentru acel utilizator.
?. 4rogramul va lucra pe o structur de date virtual declarat cu &65H-, care se aplic
peste zona utilizatorului activ.
M. Fona de lucru activ se specific printr*un registru de segment care se ncarc la
activarea unui utilizator.
N. !a fiecare ntrerupere de program starea programului ntrerupt se memoreaz n zona
de lucru a utilizatorului care a fost activ (registre, /4, (lag*uri).
O. !a activarea unui nou utilizator se va ncrca din zona sa de lucru starea programului
i se va continua din punctul n care a fost ntrerupt.
/n figura urmtoare se prezint sc0ematic modul de structurare a datelor la un program
reentrant.
1
-S )rogram reentrant
&&&&&&&&&&&&
&&&&&&&&&&&& co3 pur
&&&&&&&&&&&&
DS DS
8ona 3ate user1 8ona 3ate user 8ona 3ate user!
N
S
1&&&&&&&
&&&&&&&&&
&&&&&&&&
&&&&&&&&
&&&&&&&&
&&&&&&&&
&&&&&&&
&&&&&&&
&&&&&&&
&&&&&&
Stare registre
)rogram reentrant pentru intro3ucere /i afi/are te9te pe linii
-onsiderm mai muli utilizatori care lucreaz simultan de la 1 console i introduc
fiecare c#te un text i pot fi ntrerupi dup fiecare r#nd introdus.
(iecare utilizator are o zon de date proprie de 2; linii x 9; caractere, dar cu aceeai structur.
"umrul de linii " introduse de fiecare utilizator este diferit i se tine la nceputul zonei.
4rima adres liber din text unde se va scrie urmtoarea linie este dat n al .*lea cuvnt al
zonei ("89;). /ndexarea liniilor de text se face cu %/.
&tructur Fon
; "umr linii introduse
. /ndex prima linie liber n zona
9 !inie 2
99 !inie .
N9 !inie 1
********
%eoarece folosim pentru simulare consola unui singur calculator vom stabili structura liniei
de text care va conine$
"A P "umr de caractere ateptate
"5 P "umr de caractere recepionate
"56 P "umar terminal ;,2,. (numr user)
-%A P -omanda introdus care poate fi 0 P afiare text introdus
6ext P linie text de maxim 9; carctere $ P introducere linie de text
S P &top oprire lucru pentru utilizatorul curent
Structur liniei 3e la consol
:;F N0 N* N*, -<D =inie te9t (max 9; caractere)
-omanda (A*afiare,/*introducere,&* stop)
"umr terminal (nr user)
"umr caractere recepionate
9
"umr caractere ateptate
%eoarece liniile introduse sunt de lungime variabil, trebuie pstrat lungimea lor n zona
de lucru. 4entru afiarea acestor linii s*a utilizat o macroinstruciune de afiare A(/&, care
pune dup ultimul caracter din fiecare linie semnul B, pentru ca restul de caractere p#n la 9;
s nu se afieze.
4entru a putea calcula adresa fiecrei zone, care se va ncrca n registru 3', s*a generat o
tabel de adrese zone 6F. %e aici adresa zonei se ia indexat cu numrul terminalului.
tz dd z2,z.,z1 : adrese zone de date utilizator (far)
*****
mov b0,;
mov bl,buf7. :nr terminal
and bl,;f0
s0l bx,. :"689
lds ax,tzQbxR :adresa zona
mov bx,ax
5 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
5 *++N,* * )rogram reentrant 3e intro3ucere si afisare te9te %=ab7'
5 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
: structura buf "A * nr caractere asteptate
: buf72 "5 * nr caractere receptionate
: buf7. 65 * nr terminal
: buf71 c*da A*afisare, /*introducere, &*stop
: buf79 linie text, lung+9; caractere
..N?
stiva S+><+N, stac6 : segment stiva
d> 2;;
top eAu B : virful stivei
stiva +NDS
S31 S+><+N, : segment de date
tz dd z2,z.,z1 : adrese zone de date utilizator (far)
mes db 2;,21,S/ntroduceti nr utiliz,c*da (A,/),text S,2;,21,SBS
db 2;,21
buf db 9;,;,9, %H4(;),SBS : bufer receptie
z2 d> ;,9 :nr linii si index
db 9;; dup(;) : max 2; linii89; caractere
z. d> ;,9
db 9;; dup(;) : zona date .
z1 d> ;,9
db 9;; dup(;) : zona date 1
S31 +NDS
,
8 S,*;- :structura zona date utilizator
n d> ; :nr linii introduse
index d> ; :index linie libera
tx d> 9;82; dup(@) :linii de text
8 +NDS
5 Segment 3e co3e
prr S+><+N, 2co3e2
assume cs$prr,ds$sd2,es$sd2,ss$stiva
: afisare text cu lung pe octet 2 si urmat de -5,!(
afis <0-*? buf1
pus0a
mov a0,;
mov al,buf2 :lungime
mov si,ax
mov >ord ptr buf2Qsi72R,;a;d0 :-5 si !(
mov buf2Qsi71R,SBS
mov dx,offset buf272 :inceput text
mov a0,O :afisare
int .20
popa
E"%D
:
st2 label far
mov ax,sd2
mov ds,ax
mov es,ax
mov ax,stiva
mov ss,ax
mov sp,offset top
c2$ mov a0,O
mov dx,offset mes :afisare mesa=
int .20
mov dx,offset buf:asteptare mesa=
mov a0,2;
int .20
cmp buf71,SsS :terminat
=nz c.
mov a0,9c0 : sfarsit program
int .20
c.$ mov c0,;
mov cl,buf72 :nr caractere receptionate
?
inc cx :se memoreaza si lungimea
mov b0,;
mov bl,buf7. :nr terminal
and bl,;f0
s0l bx,. :"689
lds ax,tzQbxR :adresa zona
mov bx,ax
cmp buf71,SiS :introducere
=nz c1
5 $ntro3ucere rin3 te9t
mov di,bx :inceput zona
add di,Qbx7indexR :adresa rind liber
mov si,offset buf72 : adresa rind in bufer cu lung
rep movsb :transfer rind in zona
inc Qbx7nR :nr inregistrari in zona
add Qbx7indexR,9; :index rind curent in zona
=mp c2
c1$ cmp buf71,SaS : afisare text zona selectata
=nz c2
5 0fisare te9t intro3us
mov dx,Qbx7nR :nr linii text
mov si,bx : &/+adresa zona
add si,9 :prima linie
c9$ mov cx,9; :lungime
mov di,offset buf72 : adresa rind curent
rep movsb : mutare rind in bufer
afis buf72 :afisare sir cu lung pe octet 2
dec dx :contor linii
=nz c9 :afisare rind urmator
=mp c2 :dialog * 6erminare prin & la dialog
prr E"%&
E"% &62
M

S-ar putea să vă placă și