César,
Las instrucciones que puede ejecutar un ordenador vienen determinadas por su microprocesador. Actualmente se usa la arquitectura x86 en los PCs:
http://es.wikipedia.org/wiki/Arquitectura_x86
En el nivel más cercano a la máquina tenemos las instrucciones que puede ejecutar el microprocesador. Un compilador en C traduce lógica humana a instrucciones en ensamblador (las instrucciones que procesa el microprocesador). De nivel "humano" a nivel "maquina".
La maquina virtual es una capa de abstracción por encima de las instrucciones que puede ejecutar el microprocesador. Harbour y Clipper generan "pcode" que son instrucciones que ejecuta nuestra máquina virtual y no el microprocesador directamente:
http://es.wikipedia.org/wiki/M%C3%A1quina_virtual
http://en.wikipedia.org/wiki/P-code_machine
Fijate en algo muy interesante que la misma Wikipedia comenta:
"Estos procesos no pueden escaparse de este "ordenador virtual"". Esa es una de las principales ventajas de usar una maquina virtual. No puede haber "caballos desbocados"
(programas que pierden el control y que ejecutan instrucciones erróneas que finalmente generan un crash del sistema). Hay muchas más ventajas: portabilidad del código a distintas arquitecturas, para depurar código, etc.
Se le dice programa en código "nativo" al programa que trata directamente con el microprocesador. En su propio nivel de instrucciones.
Se le dice programa en código "interpretado" al programa que no llega a tratar directamente con el microprocesador. En nuestro caso nuestras aplicaciones tratan con la maquina virtual de Harbour, no con el microprocesador directamente. La máquina virtual es la única que está autorizada para tratar con el microprocesador. La excepción a esto es cuando usamos una función en C desde Harbour. En ese momento nos "saltamos" la máquina virtual y tratamos directamente con el microprocesador.
No se si se me entiende
Puedo poner otros ejemplos, pero basicamente ese es el concepto.