Cod de intrare – intoarcerea rezultatului de catre functii
Cod de iesire
Implementarea subprogramelor in Borland C
Cod de apel – transmiterea parametrilor
Cod de intrare – intoarcerea rezultatului de catre functii
Cod de iesire
Codul de apel (1)
Cod ce se executa inainte de apelul efectiv al subprogramului
Cuprinde urmatoarele actiuni:
daca subprogramul apelat este o functie care intoarce un string, se va pune in stiva adresa stringului rezultat (segment:offset)
punerea parametrilor in stiva
executia unei instructiuni CALL pentru apelarea propriu-zisa a subprogramului, care are ca si efect salvarea in stiva a adresei de revenire (far (segment:offset) sau near (offset), in functie de tipul de apel al subprogramului)
Codul de apel (2)
push seg (rez) ;punerea în stivă a adresei stringului rezultat
push offset (rez) ;(numai pentru funcţiile care întorc string)
sub sp, parametri ;valoarea lui sp (adresa primului cuvant liber din stiva) se modifica, ;scazandu-se atatia octeti cati sunt necesari pentru depunerea parametrilor ;in stiva
push seg (adr_revenire) ;memorarea in stiva a adresei de revenire (far sau near)
push offset (ard_revenire)
jmp adr_subprogram ;salt la corpul subprogramului
Codul de apel (3)
Cod de intrare (1)
Cod care se executa la intrarea in subprogram, inainte de executia primei instructiuni a subprogramului
Consta din urmatoarele actiuni:
izolarea stivei, adica definirea bazei zonei de stiva (stackframe) utilizate la executia subprogramului
alocarea de spatiu pe stiva pt eventualul rezultat de tip diferit de string intors de acest subprogram
alocare spatiu pe stiva si realizarea copiilor locale pt parametrii de dimensiune > 4 octeti transmisi prin valoare si pt care nu s-a realizat copierea pe stiva in codul de apel
alocare spatiu pe stiva pt date locale
alocarea spatiu pe stiva pt rezultatul de tip string intors de functii apelate din subprogram
Cod de intrare (2)
push bp ; salvam BP pe stiva, pt a putea fi restaurata in codul de iesire
mov bp,sp ; BP va indica acum baza zonei de stiva (stackframe)
sub sp,n ; alocare de spatiu pe stiva pt eventualul rezultat diferit de string (n - dimensiunea
; rezultatului)
sub sp,100h ; alocarea de spatiu in stiva pentru realizarea copiilor locale ale parametrilor de tip
; string transmisi prin valoare
… ; realizarea copiei locale in spatiul alocat anterior
sub sp,locale ; alocarea pe stiva a ‘locale’ octeti pt datele locale
sub sp,100h ; alocare de spatiu pe stiva pt rezultatul de tip string intors de functii apelate din acest ; subprogram
Cod de intrare (3)
Cod de iesire (1)
Cod care se executa la iesirea din subprogram, dupa executia ultimei instructiuni din subprogram
Consta din urmatoarele actiuni:
refacerea stivei astfel incat registrii care o caracterizeaza (SS, SP si BP) sa aibe valorile pe care le-au avut inainte de intrarea in functie
scoaterea de pe stiva a parametrilor si revenirea in codul apelant (desigur, se scoate de pe stiva si adresa de revenire)
Codul de iesire (2)
mov sp,bp ;refacerea valorii lui SP
pop bp ;refacerea lui BP, eliberarea stivei de spatiul ocupat in cadrul ;codului de intrare
ret parametri ;revenirea din subprogram si scoaterea de pe stiva a parametrilor
;(‘parametri’ octeti)
Apelatorul mai trebuie sa scoata de pe stiva adresa stringului rezultat (add sp, 004).
Cod de iesire (3)
Implementarea subprogramelor in Turbo Pascal. Modele de memorie
Modelele de memorie acceptate de Turbo Assembler 2.0:
tiny : un singur segment ce contine si date si cod (pt progame .com)
small : un segment de cod si un segment de date (cel mai utilizat)
medium : mai multe segmente de cod, un segment pt. date+stiva
compact : un segment de cod, mai multe segmente de date, mai multe segmente de stiva
large : mai multe segmente pt cod, date si stiva
huge : similar cu large (diferente in dimensiunea datelor care pot fi declarate in segmentul de date)
Harta memoriei Turbo Pascal
Cod de apel – transmiterea parametrilor (1)
apelul poate fi far sau near
parametrii se pun pe stiva in ordinea in care apar, de la stanga la dreapta
pt. parametrii transmisi prin valoare reprezentati pe 1, 2 sau 4 octeti, se pune pe stiva valoarea parametrului (daca parametru e octet pe stiva se pune un cuvant al carui octet inferior este valoarea parametrului; daca parametrul este pe 4 octeti, pe stiva se pun 2 cuvinte cu valoarea lui, intai cuvantul superior)
pt. parametrii transmisi prin referinta si pt. parametrii transmisi prin valoare reprezentati pe > 4 octeti (ex. string, array) pe stiva se pune adresa acestora (far sau near)
Cod de apel – transmiterea parametrilor (2)
Cod de apel – tipuri de apel
Se vor apela FAR:
subprograme declarate in sectiunea interface a unui unit
subprograme declarate in urma unei directive de compilare {$F+} sau declarate cu directiva FAR
subprograme declarate la nivelul cel mai exterior al unui program, daca compilarea se face cu optiunea de apel FAR implicit
Se vor apela NEAR:
subprograme declarate la nivelul cel mai exterior al unui program, daca compilarea se face fara optiunea de apel FAR implicit
subprograme declarate folosind directiva NEAR sau care nu urmeaza dupa un {$F+}
subprograme declarate in sectiunea implementation
Cod de intrare – intoarcerea rezultatului de catre functii
rez. intreg:
pe 1 octet -> AL
pe 2 octeti -> AX
pe 4 octeti -> DX:AX
rez. real -> DX:BX:AX
rez. reprezentat in virgula flotanta -> registrii coprocesorului numeric
rez. string : intr-o zona de memorie a carei adresa este plasata (de catre codul de apel) pe stiva inainte de parametrii actuali
rez. pointer : in DX – segmentul, in AX - offsetul
Exemplu
program Exemplu1;
var AY: Byte;
AS, S: String;
Procedure A (X: Integer; var Y:Byte; S: String);
1 begin
2 Y := Lo(X);
3 end;
Function B(N: Integer): String;
var T: Real;
4 begin
5 B[0] := Chr(N);
6 end;
7 begin
8 A(5, AY, AS);
9 S := B(7);
10 end.
Cod de apel - exemplu
Codul de apel generat in linia 8 ( A(5, AY, AS) ):
mov ax, 0005h
push ax ; pune in stiva valoarea parametrul X
mov di, 0050h ; di <- deplasamentul lui AY în segmentul de date
push ds ; pune in stiva adresa de segment a lui AY
push di ; pune in stiva offset-ul lui AY
mov di, 0052h ; di <- offset-ul lui AS
push ds ; pune in stiva adresa de segment a lui AS
push di ; pune in stiva offset-ul lui AS
call EXEMPLU1.A ; apelul efectiv
Cod de intrare – exemplu (1)
Codul de intrare generat la intrare in procedura A (linia 1):
push bp
mov bp, sp ; izolarea stivei
mov ax, 0100h
call 689C:02CDh
sub sp, 0100h ; alocare spatiu pe stiva pt copia locala a parametrului de tip string
mov bx, ss ; transmis prin valoare
mov es, bx
mov bx, ds
cld
lea di, [bp-100]
lds si, [bp+4]
lodsb
stosb
xchg cx, ax
xor ch, ch
rep movsb
mov ds, bx ; copierea propriu-zisa a stringului pe stiva
Cod de intrare – exemplu (2)
Cod de intrare generat la intrarea in functia B (linia 4):
push bp
mov bp, sp
mov ax, 0006
call 689Ch:02CDh
sub sp, 0006 ; alocare spatiu pt variabila de tip real
Cod de apel generat pt functia B (linia 9):
lea di, [bp-0100h]
push ss
push di ; punerea pe stiva a adresei pt rezultat de tip string
mov ax, 0007
push ax
call EXEMPLU1.B
add sp, 0004 ; scoaterea de pe stiva a adresei rezultatului
Cod de iesire - exemplu
Cod de iesire din procedura A (linia 3):
mov sp, bp
pop bp
ret 000Ah ; scoaterea de pe stiva a 10 octeti
Cod de iesire din functia B (linia 6):
mov sp, bp
pop bp
ret 0002 ; scoaterea de pe stiva a 2 octeti
Implementarea subprogramelor in Borland C. Cod de apel
Apelul este FAR sau NEAR in functie de modelul de memorie folosit
Parametrii se transmit numai prin valoare
Parametrii de pun in stiva de la dreapta la stanga
pe stiva se pune 1 cuvant pt. char, enum, int, pointer near
pe stiva se pune 2 cuvinte pt. date reprezentate pe 4 octeti ca long si pointeri far
parametrii reali (float, double si long double) si struct se copiaza pe stiva
Cod de intrare
Compilatorul scutit de generare de cod care sa copieze local pe stiva parametrii transmisi prin valoare cu dimensiunea mai mare de 4 octeti
Intoarcerea rezultatului de catre functii se face asemanator cu intoarcerea rezultatului in Pascal
Cod de iesire
Scoaterea parametrilor de pe stiva revine apelantului