No, per niente. È perfettamente possibile (e spesso anche preferibile) che il compilatore emetta invece il codice assembly. L'assemblatore si occupa quindi di creare il codice macchina effettivo.
A proposito, la tua distinzione tra implementazione non VM e implementazione VM non è utile.
-
Per i principianti, l'utilizzo di una VM o la pre-compilazione su codice macchina sono solo modi diversi di implementare una lingua; nella maggior parte dei casi è possibile implementare una lingua utilizzando entrambe le strategie. In realtà ho dovuto usare un interprete in C ++ una volta.
-
Inoltre, molte macchine virtuali come la JVM hanno sia un codice macchina binario che un assemblatore, proprio come un'architettura ordinaria.
Il LLVM (che è usato dai compilatori Clang) merita una menzione speciale qui: definisce una VM per cui le istruzioni possono essere rappresentate come byte code, assembly testuale o una struttura dati che rende molto facile emettere da un compilatore. Quindi, anche se sarebbe utile per il debug (e per capire cosa stai facendo), non dovresti nemmeno sapere del linguaggio assembly, solo riguardo all'API LLVM.
La cosa bella del LLVM è che la sua VM è solo un'astrazione, e che il codice byte non viene solitamente interpretato, ma in realtà è JITted trasparente. Quindi è del tutto possibile scrivere una lingua compilata in modo efficace, senza dover mai conoscere il set di istruzioni della CPU.