Instrukce RET funguje tak, že vybere data na vrcholu zásobníku (za standardní situace na x86 to je 32 bitů), interpretuje je jako adresu a skočí na ni. Takže návratová adresa v době, kdy se vykonává instrukce RET je přímo na vrcholu zásobníku.
Framepointer (na x86 registr EBP) se ukládá na začátku podprogramu. Slouží k tomu, aby se snadno dalo přistupovat k hodnotám parametrů a lokálních proměnných (na rozdíl od registru ESP se totiž při vykonávání normálního podprogramu "nehýbe"). Situace je přitom taková, že:
[EBP] obsahuje předchozí hodnotu framepointeru
[EBP+4] obsahuje návratovou adresu (bude tam skákat instrukce RET)
[EBP+8] obsahuje hodnotu prvního parametru, použije-li se volací konvence STDCALL
[EBP-x] obsahuje hodnoty lokálních proměnných
Asi ale také záleží, jak moc velké optimalizace překladač při generování strojového kódu provádí. Může třeba dojít k názoru, že lokálních proměnných je tak málo, že se nevyplatí je ukládat na zásobník...
Takže máte pravdu, že návratová adresa neleží na vrcholu zásobníkového rámce. Leží na vrcholu zásobníku v okamžiku, kdy se vykonává instrukce RET. Tehdy už zásobníkový rámec pro daný podprogram (který je právě ukončován) neexistuje.
Instrukce RET
Zdravím,
Instrukce RET funguje tak, že vybere data na vrcholu zásobníku (za standardní situace na x86 to je 32 bitů), interpretuje je jako adresu a skočí na ni. Takže návratová adresa v době, kdy se vykonává instrukce RET je přímo na vrcholu zásobníku.
Framepointer (na x86 registr EBP) se ukládá na začátku podprogramu. Slouží k tomu, aby se snadno dalo přistupovat k hodnotám parametrů a lokálních proměnných (na rozdíl od registru ESP se totiž při vykonávání normálního podprogramu "nehýbe"). Situace je přitom taková, že:
Asi ale také záleží, jak moc velké optimalizace překladač při generování strojového kódu provádí. Může třeba dojít k názoru, že lokálních proměnných je tak málo, že se nevyplatí je ukládat na zásobník...
Takže máte pravdu, že návratová adresa neleží na vrcholu zásobníkového rámce. Leží na vrcholu zásobníku v okamžiku, kdy se vykonává instrukce RET. Tehdy už zásobníkový rámec pro daný podprogram (který je právě ukončován) neexistuje.