In che modo Stack Machine memorizza le vars globali?

2

In che modo esattamente le macchine stack (sia le macchine virtuali che virtuali) memorizzano le variabili globali?

So che C (++) lo compilo semplicemente nel segmento .data della segmentazione della memoria di un programma.

Poi c'è JVM di Java che usa un sistema stack-heap (sia lo stack di dati che l'heap sono stack che crescono uno verso l'altro) e memorizza i locals statici nell'heap.

Il motivo di questa domanda è che sto sviluppando una VM basata su stack e sto cercando di decidere se implementare il sistema stack-heap o utilizzare il sistema di segmento dati. C

Esistono altri modi per archiviare dati globali oltre a questi due?

    
posta Nergal 16.09.2017 - 09:00
fonte

3 risposte

2

Credo che la tua domanda sia fondamentalmente conflittuale (a) il formato (file) dell'eseguibile e il set di istruzioni di una macchina virtuale - in che modo tale formato supporta la dichiarazione & accessi di globals / statics - con (b) l'implementazione sottostante di tale macchina virtuale, che può essere in C o anche in un altro linguaggio basato su VM, come Java o C #.

Riguardo al primo (il formato di istruzioni e il set di istruzioni eseguibili), ad esempio nel formato eseguibile JVM (file di classe), questo formato consente di dichiarare i campi per le classi e il campo può essere etichettato come statico o istanza. Il set di istruzioni, come le macchine reali, fornisce una modalità di indirizzamento applicabile all'accesso di variabili globali o statiche. Poiché si tratta di una macchina stack, queste modalità di indirizzamento vengono offerte all'interno di istruzioni push e pop / store che indirizzano la statistica anziché le variabili locali o le variabili di istanza.

Riguardo a quest'ultimo, poiché la macchina virtuale stessa carica quasi certamente il codice da eseguire / interpretare, non sa in anticipo circa le statistiche globali / statiche nel codice che verrà caricato. Pertanto, è estremamente poco pratico per la macchina virtuale stessa mappare globali / statici nel concetto di global / statics della lingua di implementazione e invece mapperà globals / statics in oggetti heap nel linguaggio di implementazione, traducendo le istruzioni di accesso nel vm -caricato il codice in accessi puntatore (o riferimenti oggetto) durante l'esecuzione o l'interpretazione.

Sia chiaro anche che lo stesso design per un formato di file di macchina virtuale e un set di istruzioni può essere implementato da una varietà di modi molto diversi e in diversi linguaggi di implementazione. Quindi, c'è l'astrazione che rappresenta la macchina virtuale , ovvero definendo il suo formato di file e il set di istruzioni, e poi c'è l'implementazione di un macchina virtuale che osserva / esegue quel formato e amp; set di istruzioni.

    
risposta data 16.09.2017 - 18:30
fonte
3

Una macchina stack pura non è sufficiente per implementare calcoli arbitrari. Di conseguenza, la maggior parte delle VM stack non sono macchine stack allo stato puro.

Le variabili che vengono inizializzate quando il programma è caricato non sono un gran problema, perché possono essere semplicemente allocate nella parte inferiore dello stack, superando così ogni altro valore.

Ma le macchine stack rappresentano due domande importanti:

  • Come posso accedere a valori che non sono in cima allo stack? C'è un accesso casuale alla memoria? Posso copiare riferimenti ad altri oggetti? Dovrai occuparti di matrici o elenchi in qualsiasi programma non banale.

  • Come posso conservare oggetti con vite diverse? Gli oggetti allocati allo stack devono essere deallocati nell'ordine inverso a cui sono stati allocati. Ciò rende impossibili molti programmi, in particolare per quanto riguarda le chiusure o l'OOP. È necessario un archivio / heap gratuito.

vale a dire. uno stack è un buon modello per i dati locali all'interno di una procedura, ma non per i dati condivisi tra le procedure.

Oltre alla gestione dell'heap in stile C, altre strategie riguardano:

  • ambienti o dizionari che possono contenere variabili globali o locali.
  • stack separati per dati e flusso di controllo

Vale la pena studiare la macchina SECD, una macchina stack astratta che può essere utilizzata come interprete di calcolo lambda. S, E, C, D sono registri che tengono ciascuno una pila; questi registri possono essere modificati per puntare a un altro stack. S è un ordinario stack di dati, E contiene l'ambiente (binding di variabili), lo stack di controllo C contiene il codice da eseguire e il dump D è uno stack di (S, E, C) -tuple che sono continuazioni. Questa tupla è generalmente equivalente a un indirizzo di ritorno.

    
risposta data 16.09.2017 - 12:12
fonte
2

L'importante nozione è quella delle chiusure e (in matematica) di variabili libere e vincolate . Ulteriori informazioni su λ-calcolo (e Schema ).

In un certo senso, le variabili globali o statiche (e anche le costanti letterali e le funzioni direttamente chiamate) in un programma C sono gli unici valori chiusi in una funzione C. Vedi anche questa risposta.

In Java, i dati all'interno degli oggetti possono essere pensati come valori chiusi. Si noti che static data appartiene alla classe (che è un oggetto stesso), quindi Java non ha realmente dati globali (ma maggiori informazioni su Java classloaders , incluso quello primordiale della JVM ).

BTW, sia le chiusure (o le astrazioni lambda) che gli oggetti stanno mescolando i dati con il codice.

In pratica, i dati del cliente trasmessi a richiamate possono essere pensati come valori chiusi. In altre parole, una routine di callback con i dati del client è una chiusura.

Quindi potresti considerare i valori chiusi all'interno delle chiusure come in qualche modo "globali" - al codice dei valori di chiusura.

Al contrario, non è necessario alcun segmento "dati" globali o variabili globali una volta che le chiusure sono prima classe e hai funzioni anonime (ovvero l'astrazione lambda).

Leggi assolutamente SICP , Lisp In Small Pieces , Pragmatica del linguaggio di programmazione . In seguito potresti leggere anche il Libro del drago e il manuale GC .

(Consiglio vivamente di prendere alcune settimane per leggere tutti questi primi tre libri prima di codificare la VM)

Quindi chiudi chiusure di prima classe nella tua VM. Guarda anche Lua e amp; Neko & Guile & Parrot & Ocaml VM (almeno per ispirazione) e SECD macchina.

Una volta che hai delle chiusure di prima classe, vuoi veramente avere un garbage collector .

    
risposta data 16.09.2017 - 11:18
fonte

Leggi altre domande sui tag