Oppure

Loading
20/12/16 17:45
Godrek
Provo a cercarlo di spiegare passo passo:

Le regole sono le seguenti:

Come viene rappresentata (attraverso la pila di frame) l'esecuzione di un blocco:
- Quando si entra in un blocco si aggiunge un frame vuoto in cima alla pila
- Le dichiarazioni del blocco aggiungono associazioni sul frame in cima alla pila
- All'uscita del blocco si cancella il frame in cima alla pila

Come viene rappresentata (attraverso la pila di frame) quando una funzione viene chiamata:
- Se la funzione chiamata ha dei parametri formali viene aggiunto un frame in testa alla pila contenente i nomi dei parametri formali con associati i valori degli argomenti passati attraverso la chiamata di funzione
- Si esegue il corpo (il blocco) che definisce la funzione (quindi si aggiunge un frame vuoto in cima, .... , si cancella il frame in cima)
- Al termine della funzione si cancella il frame in testa alla pila (ovvero il frame contenente i parametri della funzione)


int a = 10;

int somma(int b)
{
     return a + b;
}

int main()
{
    int x = 15;
    x = somma(x);
    return 0;
}

Supponendo di partire da una pila vuota, secondo le regole elencate, la rappresentazione attraverso una pila di frame di tale programma è la seguente:

1° passo: int a = 10; - aggiungo un frame in testa alla pila contenente l'associazione: (a, 10)

2° passo: int somma(int b) - aggiungo una associazione sul frame in testa alla pila contenente l'associazione (un po astratta): (somma, definizione)

3° passo: int main() - aggiungo un frame vuoto in testa alla pila

4° passo: int x = 5; aggiungo una associazione sul frame in testa alla pila contenente l'associazione: (x, 15)

5° passo: x = somma(x) (chiamata della funzione somma) - aggiungo un frame in testa alla pila contenente i parametri di somma...

Questo è il punto:
- int somma (){...}
- int main(){...}

hanno entrambi la sintassi di una definizione di funzione, soltanto che quando dichiaro la funzione somma aggiungo prima una associazione: (somma, definizione) e solamente quando tale funzione viene chiamata aggiungo un frame in testa alla pila contenente le sue variabili locali, mentre quando dichiaro la funzione main non viene aggiunta una associazione: (main, definizione) ma viene aggiunto direttamente un frame contenente le sue variabili locali.
Quindi è come se il compilatore avesse bisogno di sapere (prima del suo uso) quali sono le variabili locali che appartengono alla funzione somma, mentre per quanto riguarda le variabili locali della funzione main non ne ha bisogno.
Ultima modifica effettuata da Godrek 20/12/16 18:36
aaa
20/12/16 19:26
pierotofy
1° passo: int a = 10; - aggiungo un frame in testa alla pila contenente l'associazione: (a, 10)


No. Non so dove hai trovato queste informazioni (o chi te le ha comunicate), ma non funziona cosi'. int a = 10 e' una variabile globale, e viene referenziata senza l'uso di nessuno stack frame (non avrebbe senso).

Prendi le note del tuo corso e mettile da parte! Comincia da zero e rileggi i seguenti argomenti:

it.wikipedia.org/wiki/…
en.wikipedia.org/wiki/…

Non guardare il programma in C! Leggi il listino in Assembly (cerca su Google le basi di Assembly per x86) e capirai meglio come funziona. Assembly e' una rappresentazione 1 ad 1 di quello che viene effettivamente eseguito sul computer, C e' un linguaggio ad alto livello e non saprai mai con certezza cosa succede all'interno!
Ultima modifica effettuata da pierotofy 20/12/16 19:28
Il mio blog: piero.dev
20/12/16 20:12
Godrek
Hai ragione. Ho appena letto, correggetemi se è giusto, che la memoria RAM è suddivisa in 4 parti:
- area codice
- area variabili globali
- area stack
- heap

e le variabili globali non vanno sullo stack, ma in esso vanno soltanto le variabili locali delle funzioni.

Per quanto riguarda la definizione di una funzione, cosa succede, nello stack frame, quando una funzione viene definita?
E quando viene chiamata?

Per quanto riguarda l'assembly non ci capisco niente e per ora, a causa degli esami, non avrei neanche tempo da dedicarci.
Ultima modifica effettuata da Godrek 20/12/16 20:16
aaa
20/12/16 20:28
pierotofy
Postato originariamente da Godrek:

Hai ragione. Ho appena letto, correggetemi se è giusto, che la memoria RAM è suddivisa in 4 parti:
- area codice
- area variabili globali
- area stack
- heap

e le variabili globali non vanno sullo stack, ma in esso vanno soltanto le variabili locali delle funzioni.


E' una generalizzazione e non e' sempre corretto, ma a volte il layout e' quello che hai descritto. Non si parla inoltre di "memoria RAM" che comprende tutta la memoria disponibile, ma dell'"area di memoria allocata per il processo".

Per quanto riguarda la definizione di una funzione, cosa succede, nello stack frame, quando una funzione viene definita?


Niente! Una funzione e' definita nella .code o .text section. Cosa c'entrano gli stack frame?

E quando viene chiamata?


Dipende dalla convenzione usata... cdecl, syscall, stdcall, fastcall, etc. etc. per questo devi leggere l'Assembly!

Per quanto riguarda l'assembly non ci capisco niente e per ora, a causa degli esami, non avrei neanche tempo da dedicarci.


Mi dispiace, ma non penso riuscirai a capire il funzionamento di quello di cui stiamo parlando. E' come cercare di capire la grammatica francese senza aver studiato francese.
Il mio blog: piero.dev
21/12/16 15:04
lumo
È vero che senza una conoscenza anche minima di assembly non si possono capire a fondo queste cose, però puoi ugualmente capire gli stack frame guardando come viene eseguito un programma in C.
In teoria basterebbe fare un po' di prove con le funzioni e vedere cosa succede, altrimenti impara ad usare un debugger (spesso gli IDE ne hanno uno integrato relativamente facile da usare). A quel punto ti basta andare di "step" per il codice.

La spiegazione semplificata (e, diciamolo, sbagliata) degli stack frame che ti hanno dato puoi a mio modesto parere buttarla nel cassonetto della spazzatura.
aaa