Domanda

Sono molto curioso di memoria stack organizzazione dopo che mi sperimentare che cosa sta succedendo in background e, ovviamente, visto l'abbinamento con piccola conoscenza che ho acquisito da libri.Volevo solo verificare se quello che ho capito è corretto.

Ho un programma fondamentale-ha 2 funzioni, la prima è pippo e l'altro è il principale (il punto di ingresso).

void foo(){
    // do something here or dont
}

int main(){

    int i = 0;

    printf("%p %p %p\n",foo, &i, main);

    system("PAUSE");
    return EXIT_SUCCESS;
};

L'output del programma è riportato di seguito, le principali variabili locali che mi trova completamente in una posizione senza rapporto.integer è un tipo di valore, ma controllare di nuovo con un char * puntatore locale principale e ottenere risultati simili.

00401390 0022FF44 00401396
Press any key to continue . . .

Principalmente ho capito che il codice e le variabili sono allocate nei diversi segmenti di memoria (segmento di codice/segmento di dati).Quindi, fondamentalmente, è giusto dire stack di chiamate crolla informazioni di base circa l'esecuzione di funzioni (locali, variabili, parametri, tornando punti) e tenerli in un segmento di dati?

È stato utile?

Soluzione

Un piccolo avvertimento all'inizio:tutte queste risposte sono un po ' influenzata dal sistema operativo e l'architettura hardware.Windows fa cose abbastanza radicalmente diverso da UNIX-like, linguaggi, sistemi operativi real-time e piccola vecchia di sistema UNIX.

Ma le risposte di base come @Richie e @Paolo, hanno detto, è "sì". Quando il compilatore e linker ottenere attraverso con il codice, è suddiviso in ciò che è noto come "testo" e "dati" segmenti di UNIX.Un segmento di testo contiene le istruzioni e alcuni tipi di dati statici;un segmento di dati contiene, bene, i dati.

Una grossa fetta del segmento di dati viene poi assegnato per lo stack e heap space.Altri pezzi che possono essere imputati a cose come statico o extern strutture di dati.

Quindi sì, quando il programma viene eseguito, il contatore di programma è assiduamente il recupero di istruzioni da un diverso segmento di dati.Ora entriamo in alcune architettura dipendenze, ma in generale, se avete memoria segmentata, le tue istruzioni sono costruiti in modo che il recupero di un byte da segmenti è il più efficiente possibile, Nella vecchia 360 architettura, avevano base dei registri, in x86 avere un sacco di capelli che crescevano come spazio di indirizzi è andato al vecchio 8080 per i processori moderni, ma tutte le istruzioni sono molto ottimizzato, perché, come potete immaginare, il recupero di istruzioni e gli operandi sono molto intensamente utilizzato.

Ora, noi et per più moderne architetture della memoria virtuale e unità di gestione della memorias.Ora la macchina ha un hardware specifico che il programma trattare l'indirizzo di spazio come un grande piatto intervallo di indirizzi;i vari segmenti di ottenere semplicemente in quel po ' di spazio di indirizzi virtuali.La MMU lavoro è quello di prendere un indirizzo virtuale e tradurlo in un indirizzo fisico, compreso che cosa fare se l'indirizzo virtuale non capita di essere nella memoria fisica a tutti al momento.Di nuovo, la MMU hardware è molto molto ottimizzati, ma questo non significa che non c'è no prestazioni costo associato.Ma come processori hanno ottenuto più veloce ed i programmi hanno goten più grande, è diventato meno importante.

Altri suggerimenti

Sì, è esattamente vero. Codice e dati vivono in diverse parti della memoria, con autorizzazioni diverse. Lo stack contiene parametri, indirizzi di ritorno e variabili locali (& Quot; automatiche & Quot;) e vive con i dati.

Sì.

Immagina che la tua memoria di codice sia ROM e che la tua memoria di dati sia RAM (una comune architettura a chip piccolo). Quindi vedi lo stack deve essere nella memoria dei dati.

Bene, posso parlare per SPARC:

Sì. Quando si esegue il programma, il programma viene letto due volte (almeno in SPARC). Il programma viene caricato in memoria e tutte le allocazioni di array / stack vengono caricate in seguito. Nel secondo passaggio attraverso il programma, gli stack vengono allocati in memoria separata.

Non sono sicuro per i processori basati su CISC, ma sospetto che non vari troppo.

Il tuo programma mostra comportamenti indefiniti proprio perché:

  • non riesci a includere <stdio.h> o <cstdio> a seconda della lingua in cui stai compilando il codice come
  • printf e tutte le funzioni degli argomenti variabili non hanno la capacità di controllare i loro argomenti. Quindi è obbligatorio da parte tua passare argomenti correttamente digitati. Dovresti davvero fare:
  • system() non ha dichiarazioni nell'ambito. Includi <stdlib.h> o <cstdlib> a seconda dei casi.

Scrivi il tuo codice come:

   #include <stdio.h>

   int main() {
      /* ... */
      printf("%p %p %p\n", (void *)foo, (void *)&i, (void *)main);
      /* ... */
   }

Nota anche che:

  • La definizione di void foo() non è un prototipo in C, ma in C ++. Tuttavia, se dovessi scrivere void foo(void) otterrai un prototipo in entrambe le lingue.
  • <=> dipende dall'implementazione: il codice potrebbe non funzionare come previsto su tutte le piattaforme.

Il linguaggio proprio (C o C ++) non pone alcuna limitazione su come organizzare la memoria. Non ha nemmeno il concetto di uno stack o di un heap. Questi sono definiti dalle implementazioni che ritengono appropriate. Idealmente, dovresti consultare la documentazione fornita dalla tua implementazione per avere una buona idea di ciò che fanno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top