Ceea ce urmează descrie comportamentul stiva de apel în funcție si. Detalii sunt adevărate pentru compilator gcc pe platforma Intel Pentium. Există multe modalități și acorduri pentru a crea și de a umple cadrul: procesoare diferite, sisteme de operare și compilatoare pot face acest lucru în diferite moduri.
funcţia de apel
În cazul în care funcția apelată funcționează cu registrele EAX, ECX și EDX, apelantul trebuie să le salveze într-un fel pe stivă înainte de a apela subrutina. Pe de altă parte, numita funcție este de a restabili valorile acestor registre. În cazul în care numita funcție modifică starea registrului EAX, ECX și EDX, acesta trebuie să salvați mai întâi starea anterioară pe stivă, și înainte de a merge pentru readucerea lor la valorile lor inițiale.
Parametrii trecut la foo funcția sunt plasate pe stiva de la dreapta la stânga: în primul rând, ultimul argument la sfârșitul prima. Variabilele locale, precum și de timp, este stocat pe stivă.
Luați în considerare un proces în trepte de apel și urmăriți schimbările în stivă.
Acțiunile apelantului înainte de apel
În acest exemplu, funcția principală de asteptare, și numit foo. Înainte de a apela funcția principală utilizează ESP și EBP înregistrează pentru a lucra cu propriul său cadru.
1. Funcția principală pune pe stivă conținutul registrelor EAX, ECX și EDX. Aceasta este o acțiune opțională care are loc numai în cazul în care starea registrelor trebuie să fie salvate.
2. Funcția principală pune pe argumentele stiva, începând cu ultima. De exemplu, în cazul în care apelul este de forma
a = foo (12, 15, 18);
de asamblare ar putea arata ca:
3. solicită principale apela apelul subrutina
Fig. 2 frame stare după un apel de apelFigura 2 prezintă conținutul cadrului, după o funcție de apel îndeplinită. Linia roșie de pe acest lucru și următoarele cifre separă conținutul stivei, care a fost creat printr-un apel funcție de restul conținutului. După apelarea funcției în partea de sus a stivei va fi din nou în această poziție.
Acțiunile de asteptare funcția după apel
W găină foo funcția preia controlul, trebuie să facă 3 lucruri: configurați cadrul dvs., să aloce spațiu pentru stocarea locală, după cum este necesar pentru a menține starea EBX, ESI si EDI.
Astfel, foo stabilește mai întâi propriul cadru. Mai EBP indică poziția principală cadru. Această valoare trebuie să fie păstrată, de aceea este pus pe stivă. Conținutul mutat la EBP ESP. Acest lucru va permite mânerul la argumentele de funcții, cum ar fi trecerea de la EBP și fără ESP stiva indicator pentru acțiuni suplimentare. Prin urmare, aproape toate funcțiile B încep cu instrucțiunile
Fig. 3 cadru după apelarea apelului: functia apelata a păstrat valoarea de bază indicatorul funcție principalăPentru variabilele locale și depozitarea temporară pot fi accesate acum dintr-o deplasare în raport cu EBP. În concluzie, foo ar trebui să salveze conținutul EBX, ESI si EDI pe stivă. în cazul în care acestea sunt utilizate.
Fig. 4 Funcția Acum foo poate îndeplini corpul tauAcum, ea poate fi format funcții ale corpului. În acest caz, noile date pot fi introduse și scoase din stivă. Prin urmare, ESP stiva indicator poate fi schimbat, dar EBP rămâne fixă, iar primul argument poate fi accesat [EBP + 8], indiferent de cât de multe operațiuni de împingere și pop a fost determinată. Alim funcție, la rândul său, poate duce, de asemenea, la alte apeluri de funcții sau un apel recursiv. Cu toate acestea, din moment ce EBP este restabilită după întoarcerea de la aceste apeluri imbricate, trimiterile la argumente, variabile locale și lucruri de depozitare temporară pot fi, de asemenea, face prin deplasarea în raport cu EBP.
Acțiunile numite funcții înainte de a reveni
N Înainte de a reveni la controlul apelantului, foo ar trebui să fie definite astfel încât să se întoarcă o valoare, așa cum am menționat deja. Rezultatul este plasat în EAX registru sau să fie un parametru suplimentar al funcției, iar funcția nu va returna o valoare.
În al doilea rând, foo trebuie să restabilească valoarea EBX, ESI si EDI. La începutul apelului, vom plasa o valoare pe registrele stiva (ca funcția noastră de a le schimba), și sunt acum în măsură să elimine aceste valori de acolo, dar numai în cazul în care ESP păstrează valoarea corectă, și anume cantitatea de împingere și funcționarea pop trebuie să fie echilibrat.
După aceste două etape ale variabilelor locale și de depozitare temporară nu mai este necesară, iar rama poate fi îndepărtată urmând instrucțiunile
Fig. 5 Biroul a revenit funcția principalăAcțiuni funcția de apelare după întoarcerea
Upă fiind controlul vyzyvayuscheo trecut la funcția (în acest exemplu, principal), argumentele trecut la funcția este, de obicei, nu mai este necesară. Ne putem retrage din stivă, toate cele trei valori dintr-o dată, pur și simplu prin adăugarea a 12 (3 × 4 octeți) la indicatorul de stivă.
În cele din urmă, în cazul în care conținutul EAX înregistra, ECX și EDX a fost salvat pe stivă, acesta poate fi restaurat. Astfel, stiva este din nou în starea în care apelul a fost să funcționeze.
ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 [email protected] studenți Stepan Sypachev
Încă nu este clar? - întrebări scrie pe cutie