Come vengono creati gli indirizzi di memoria?

-3
#include <stdio.h>

int main()
{
    size_t a = 2;
    size_t *p = &a;
    printf("%p\n", p);
}

Il codice precedente stamperà l'indirizzo di memoria di a . Capisco che all'interno di un sistema operativo, questo indirizzo si riferisce a un indirizzo virtuale e non alla memoria effettiva.

Tuttavia, la compilazione di un codice simile (osdev.org) e l'esecuzione come un vero kernel produrrà numeri sullo schermo. Da dove vengono questi numeri / indirizzi? gli indirizzi di memoria sono codificati in modo rigido quando vengono fabbricati?

    
posta Josh l 16.09.2018 - 02:03
fonte

2 risposte

3

Gli indirizzi non lo sono, ma il loro offset è quando il programma è compilato. Quando il programma è caricato in memoria dal sistema operativo, l'avvio del programma è noto (perché è lì che il sistema operativo lo carica). Aggiungi l'offset e il puntatore è noto.

In questo programma, la variabile essendo una variabile locale alla funzione complica un po 'le cose. Lo stesso tipo di concetto di offset si applica alle funzioni, anche se vengono caricate secondo necessità durante l'esecuzione del programma. Ma anche loro sono caricati all'ingrosso in memoria con ogni variabile che di solito ha il proprio offset dall'inizio dello spazio di stack della funzione.

Ma dato che questo è main e la dimensione del programma, lo spazio dello stack potrebbe non essere allocato in fase di runtime.

Il concetto è lo stesso però. Il sistema operativo ti dà un indirizzo iniziale e le tue variabili sono un po 'sfalsate in un blocco di memoria.

    
risposta data 16.09.2018 - 02:55
fonte
2

Stai chiedendo in che modo le variabili locali ottengono i loro indirizzi.

Le variabili locali sono posizionate su una pila di runtime. Questo viene fatto dinamicamente: quando ogni funzione viene chiamata, viene attivata creando una nuova copia del suo stack frame; questa copia viene effettivamente inserita nello stack, quindi la sua posizione ha a che fare sia con la posizione dello stack, sia con quello che altro (altre funzioni) erano nello stack al momento - cioè la catena di chiamate dinamica.

Lo stack frame per una funzione è un oggetto il cui layout è impostato dal compilatore o dal programmatore della lingua assembly, in qualche modo simile ad altri oggetti come struct o classes (che sono variabili locali o vanno nell'heap). Variabili come a nella funzione sono come i campi in questo oggetto frame stack.

Si noti che questo meccanismo di stack dinamico supporta naturalmente la ricorsione: una funzione può essere attivata più volte, nel senso che una variabile locale potrebbe verificarsi in più posizioni nello stack in caso di ricorsione. Questo dovrebbe enfatizzare la natura dinamica del record di attivazione del frame dello stack.

La posizione dello stack di runtime è determinata dal sistema operativo; è assegnato come oggetto nello spazio degli indirizzi del processo.

In ogni caso, queste sono tutte solo strutture dati; alcuni sono come le classi (cioè i metadati che descrivono dati, campi e loro offset e altri sono come le istanze): lo stack è una struttura di dati nel processo; il frame dello stack è una descrizione di un record di attivazione; il record di attivazione è una struttura di dati all'interno dello stack. Una variabile (come a ) è un campo nel record di attivazione.

Come puoi vedere, una struttura dati può esistere all'interno di un'altra (stack all'interno di un processo, stack frame all'interno di una pila). Gli indirizzi dei singoli campi e variabili vengono creati tramite la posizione della struttura dati esterna e gli offset della struttura del campo o dei dati interni all'interno di tale struttura dati e così via, in modo ricorsivo.

Lo stesso vale se il thread è un thread del kernel o un thread utente.

    
risposta data 16.09.2018 - 23:39
fonte

Leggi altre domande sui tag