Perché le macchine virtuali devono essere "stack machine" o "register machines" ecc.?

46

(Questa è una domanda estremamente newbie-ish).

Ho studiato un po 'su Virtual Machines.

Molti di questi sono progettati in modo simile ai computer fisici o teorici.

Ho letto che la JVM, ad esempio, è una "macchina stack". Cosa significa (e correggimi se ho torto) è che memorizza tutta la sua 'memoria temporanea' su uno stack e fa operazioni su questo stack per tutti i suoi opcode.

Ad esempio, il codice sorgente 2 + 3 verrà tradotto in bytecode simile a:

push 2
push 3
add

La mia domanda è questa:

Le JVM sono probabilmente scritte usando C / C ++ e così via. In tal caso, perché la JVM non esegue il seguente codice C: 2 + 3 ..? Voglio dire, perché ha bisogno di uno stack, o in altri "registri" di macchine virtuali - come in un computer fisico?

La CPU fisica sottostante si occupa di tutto questo. Perché i writer VM non eseguono semplicemente il codice byte interpretato con istruzioni "normali" nella lingua con cui è stata programmata la VM?

Perché le macchine virtuali devono emulare l'hardware, quando l'hardware effettivo lo fa già per noi?

Ancora una volta, domande molto newbie-ish. Grazie per il tuo aiuto

    
posta Aviv Cohn 08.06.2014 - 22:18
fonte

4 risposte

50

Una macchina, virtuale o meno, ha bisogno di un modello di calcolo che descrive come viene eseguito il calcolo su di esso. Per definizione, non appena calcola, implementa un modello di calcolo. La domanda quindi è: quale modello dovremmo scegliere per la nostra VM? Le macchine fisiche sono limitate da ciò che può essere fatto in modo efficace ed efficiente nell'hardware. Tuttavia, come si nota, le macchine virtuali non hanno vincoli di questo tipo, sono definite nel software utilizzando linguaggi di alto livello arbitrari.

Esistono, infatti, macchine virtuali di alto livello come descrivi. Sono chiamati linguaggi di programmazione . Lo standard C ad esempio dedica la maggior parte delle sue pagine alla definizione di un modello per la cosiddetta "macchina astratta C" che descrive come si comportano i programmi C, e per estensione (come regola if) come un compilatore C conforme (o interprete) dovrebbe comportarsi.

Naturalmente, di solito non chiamiamo una macchina virtuale. Di solito una macchina virtuale significa qualcosa di più basso, più vicino all'hardware, non destinato a essere programmato direttamente, progettato per essere eseguito in modo efficiente. Questo errore di selezione significa che qualcosa che accetta codice componibile di alto livello (come quello che descrivi) non sarebbe considerato una VM perché è eseguito codice di alto livello.

Ma per ottenere il punto, ecco alcuni motivi per fare una VM (come in, qualcosa preso di mira da un compilatore bytecode) basata su registro o simili. Le macchine stack e register sono estremamente semplici. C'è una sequenza di istruzioni, alcuni stati e semantica per ogni istruzione (una funzione Stato - > Stato). Nessuna riduzione complessa dell'albero, nessuna precedenza dell'operatore. L'analisi, l'analisi e l'esecuzione è molto semplice, perché è un linguaggio minimale (lo zucchero sintattico è compilato) e progettato per essere letto da macchina piuttosto che da lettura umana.

Al contrario, analizzare anche i linguaggi C più semplici è piuttosto difficile, e l'esecuzione richiede analisi non locali come il controllo e la propagazione dei tipi, la risoluzione dei sovraccarichi, la manutenzione di una tabella dei simboli, la risoluzione degli identificatori string , trasformando il testo lineare in un AST preceduto dalla precedenza e così via. Si basa su concetti che sono naturali per gli esseri umani, ma devono essere accuratamente invertiti dalle macchine.

Il bytecode JVM, ad esempio, viene emesso da javac . Non ha praticamente bisogno di essere letto o scritto dagli umani, quindi è naturale orientarlo verso il consumo da parte delle macchine. Se lo hai ottimizzato per gli esseri umani, la JVM dovrebbe solo leggere ogni avvio del codice, analizzarlo, analizzarlo e convertirlo in una rappresentazione intermedia simile a un modello di macchina semplificato comunque . Potrebbe anche tagliare l'uomo medio.

    
risposta data 08.06.2014 - 22:50
fonte
19

Questa risposta si concentra sulla JVM, ma in realtà si applica a qualsiasi VM.

Why do VMs need to emulate hardware, when the actual hardware already does this for us?

Non lo fanno, ma rendono la VM molto più semplice e portatile: una VM che emula l'hardware può utilizzare lo stesso modello di calcolo di qualsiasi CPU hardware.

La JVM in particolare è stata costruita pensando alla portabilità, infatti è stata costruita in modo da poter essere implementata anche nell'hardware (potrebbe essere difficile crederlo oggi, ma origine di Java era nel mondo embedded - in particolare, i controller per la televisione interattiva).

Se si ha un obiettivo come questo, è auspicabile che la VM lavori il più vicino possibile ad una macchina fisica, perché la conversione in codice macchina reale diventa più facile e quindi più veloce. Una volta che hai gli opcode della VM, in teoria, tutto ciò che devi fare è tradurre in opcode della CPU su cui il programma gira effettivamente. In pratica non è esattamente così semplice.

I mean, why does it need a stack, or in other VMs 'registers' - like in a physical computer?

L'uso di un modello di macchina virtuale basato sullo stack ha il vantaggio che può essere facilmente trasferito su entrambe le macchine di registrazione e stack, mentre l'opposto non è necessariamente vero. Una macchina virtuale basata su registro dovrebbe fare ipotesi sul numero di registri, sulla dimensione dei registri, ecc. Con una macchina stack, non sono necessarie tali ipotesi.

The underlying physical CPU takes care of all of this. Why don't VM writers simply execute the interpreted bytecode with 'usual' instructions in the language the VM is programmed with?

Bene, questo è ciò che fanno queste VM, interpretano il bytecode. Anche la JVM lo fa, almeno prima che JIT (just-in-time) intervenga: interpreta i codici byte ed esegue le istruzioni nel linguaggio in cui è stata scritta la JVM (tipicamente C o C ++, ma ce n'è anche una scritta in JavaScript, Doppio ). Si noti, tuttavia, che anche tali dichiarazioni sono state tradotte in codice macchina da un compilatore e in realtà sono molto simili a ciò che produce il compilatore Java, ovvero utilizzano registri e stack per eseguire il proprio lavoro. Nota l'uso di "interpretato" v.s. le lingue "compilate" diventano un po 'sfocate a questo punto.

    
risposta data 09.06.2014 - 00:57
fonte
9

Perché le macchine virtuali devono essere "macchine stack" o "macchine di registro" ecc.?

Non lo fanno. Se hai bisogno di una macchina virtuale, potrebbe essere qualsiasi cosa.

Le macchine virtuali esistenti sono apparse come soluzioni a situazioni come: Mi è venuta in mente un'idea davvero geniale, ho inventato un nuovo linguaggio di programmazione! Ma devo generare codice. (Che compito noioso!) Ma non voglio generare codice i8086 perché è brutto, e non voglio generare codice 68k perché tutti usano Intel. C'è anche VAX, ma non ho alcun VAX, né un computer né un libro VAX. Pertanto genererò il codice per alcuni processori che non esistono fisicamente e implementano quel processore nel software. Le specifiche di quella VM faranno un capitolo della mia tesi. In teoria, sarà possibile compilarlo in codice nativo di qualsiasi processore, ma non sarò io.

D'altra parte, la notazione come "2 + 3" probabilmente non sarà usata dalle macchine virtuali nel prossimo futuro perché implica fare molta trasformazione prima che qualcosa possa essere eseguito.

    
risposta data 09.06.2014 - 13:09
fonte
-2

Per rispondere alla domanda effettiva che è stata posta. Il termine "MACCHINA virtuale" significa che TUTTI i software / hardware sono simulati / emulati. Se usi il software / hardware sottostante per eseguire le istruzioni, allora non hai una VM, hai un compilatore / interprete.

    
risposta data 30.10.2017 - 02:03
fonte

Leggi altre domande sui tag