5

Me llamó la atención algunos emuladores y máquinas virtuales usan recompilación dinámica. ¿Cómo lo hacen? En C sé cómo llamar a una función en ram utilizando typecasting (aunque nunca lo intenté), pero ¿cómo se pueden leer los códigos de operación y generar código para ello? ¿La persona necesita tener pedazos prefabricados de ensamblaje y copiarlos/unirlos? es el montaje escrito en C? Si es así, ¿cómo encuentras la longitud del código? ¿Cómo contabilizas las interrupciones del sistema?¿Cómo se usa la recompilación dinámica?

operación -Editar-

interrupciones del sistema y cómo (re) compilar los datos es lo que más me interesa. Al investigar más he oído de una persona (no hay ninguna fuente disponible) js utilizados, leer el código de la máquina , salida js source y use eval para 'compilar' la fuente js. Interesante.

Respuesta

1

suena como que debe tener conocimiento del código de máquina plataforma de destino para volver a compilar dinámicamente

Sí, absolutamente. Es por eso que partes de la Máquina Virtual Java deben ser reescritas (es decir, el JIT) para cada arquitectura.

Cuando escribe una máquina virtual, tiene en mente una arquitectura de host particular y una arquitectura de invitado particular. Una máquina virtual portátil se llama mejor emulador, ya que se estaría emulando cada instrucción de la arquitectura de invitado (los registros de invitado se representarían como variables de host, en lugar de registros de host).

Cuando las arquitecturas de huésped y de host son las mismas, como VMWare, hay un montón de optimizaciones (bastante ordenadas) que puede hacer para acelerar la virtualización. Hoy estamos en el punto en que este tipo de máquina virtual es MENOS más lento que ejecutar directamente en el procesador. Por supuesto, es extremadamente dependiente de la arquitectura: probablemente sea mejor que reescriba la mayoría de VMWare desde cero que tratando de portarlo.

-1

IIS hace esto copiando en la sombra: después de la compilación, copia los ensamblajes en algún lugar temporal y los ejecuta desde la temperatura.

Imagínese, ese usuario cambie algunos archivos. A continuación, IIS recompilará asseblies en los siguientes pasos:

  1. Recompilar (todas las solicitudes tramitadas por código antiguo)
  2. Copia los nuevos conjuntos (todas las peticiones que maneja código antiguo)
  3. Todas las nuevas solicitudes serán manejadas por el nuevo código , todas las solicitudes, por viejo.

Espero que esto sea útil.

+0

Eso no es lo que estoy hablando. Estoy hablando de tomar bytes en bruto que no son IE del código fuente. Necesita escribir el compilador y cargarlo en código ingenuamente. Vi un mal ejemplo con ensamblaje en línea que creo que es un lote pero parece que no funciona, fue un mal ejemplo. –

1

Es muy posible, aunque no trivial, desensamblar el código de un puntero de memoria, optimizar el código de alguna manera y luego volver a escribir el código optimizado en la ubicación original o en una nueva ubicación con un parche de salto en la ubicación original.

Por supuesto, los emuladores y las máquinas virtuales no tienen que volver a escribir, pueden hacerlo en tiempo de carga.

+0

No creo que sea posible desensamblar código de un puntero de memoria sin conocer el procesador específico de su procesador IE. –

+0

@acidzombie: Todo lo que está hablando es específico del procesador. –

+0

@acidzombie: Correcto: esto será muy específico de la plataforma. ¿Hay algo en particular que estás tratando de lograr? –

-2

Una máquina virtual carga "código de bytes" o "lenguaje intermedio" y no código de máquina, por lo tanto, supongo, que solo recompila el código de bytes de manera más eficiente una vez que tiene más datos de tiempo de ejecución.

http://en.wikipedia.org/wiki/Just-in-time_compilation

+0

¿De verdad? Nunca escuché sobre máquinas virtuales usando bytecode en lugar de código de máquina. ¿Eres positivo? No puedo pensar en cómo las máquinas virtuales pueden tener Windows XP/7/server como bytecode antes de aplicar JIT. –

+4

@acidzombie: ah, estás confundiendo dos significados relacionados del término VM. La Máquina Virtual Java es una bestia completamente diferente de la máquina virtual VMWare. El primero simula una arquitectura Java virtual, el segundo una arquitectura real (x86). El "código de bytes" es simplemente el ensamblador de una arquitectura virtual. – MSalters

+0

@MSalters: Oh, veo lo que quieres decir. Ahora lo que quiero saber es CÓMO recompila uno. Parece que DEBO tener conocimiento del código máquina de la plataforma objetivo para recompilarlo dinámicamente. Todavía estoy interesado en cómo se manejan las interrupciones –

0

Este enfoque es utilizado habitualmente por los entornos con una representación de código de bytes intermedio (como Java, .NET) El código de bytes contiene suficientes estructuras de "alto nivel" (alto nivel en términos de nivel más alto que el código de máquina) para que la VM pueda extraer fragmentos del código de bytes y reemplazarlos por un bloque de memoria compilado. La máquina virtual suele decidir qué parte se compila contando cuántas veces se interpretó el código, ya que la compilación en sí misma es un proceso complejo y lento. Por lo tanto, es útil compilar únicamente las partes que se ejecutan muchas veces.

Pero, ¿cómo los códigos de operación de lectura y generar código para ello?

El esquema de los códigos de operación está definido por la especificación de la VM, por lo que la VM abre el archivo de programa y lo interpreta de acuerdo con la especificación.

¿Necesita la persona tener trozos de montaje prefabricados y copiarlos/combinarlos juntos? es el montaje escrito en C?

Este proceso es un detalle de implementación de la máquina virtual, por lo general hay un compilador incrustado, que es capaz de transformar la secuencia de código fuente de máquina virtual en código máquina.

¿Cómo se explican las interrupciones del sistema?

Muy simple: ninguna. El código en la VM no puede interactuar con el hardware real. La máquina virtual interactúa con el sistema operativo y transfiere eventos de sistema operativo al código saltando/llamando partes específicas dentro del código interpretado. Cada evento en el código o desde el sistema operativo debe pasar la máquina virtual.

También los productos de virtualización de hardware pueden usar algún tipo de JIT. Un caso de uso típico en el mundo X86 es la traducción del código de modo real de 16 bits al código de modo protegido de 32 o 64 bits para no tener que emular una CPU en modo real. También una máquina virtual solo de software reemplaza las instrucciones de salto en el código de ejecución por saltos en el software de control de VM, que en cada rama la siguiente ruta de código para instrucciones de salto las escanea y las reemplaza, antes de que salte al destino de código real. Pero dudo si el reemplazo del salto califica como compilación JIT.

1

Esta es una pregunta muy abierta, no estoy seguro de dónde quiere ir con ella. Wikipedia cubre el tema genérico con una respuesta genérica. El código nativo emulado o virtualizado se reemplaza por código nativo. Cuanto más se ejecuta el código, más se reemplaza.

Creo que necesita hacer algunas cosas, primero decida si está hablando de una emulación o una máquina virtual como vmware o virtualbox. Una emulación: el procesador y el hardware se emulan utilizando software, por lo que el emulador lee la siguiente instrucción, el código de operación se separa por código y usted determina qué hacer con él. He estado realizando una emulación 6502 y una traducción binaria estática, que es una recompilación dinámica pero preprocesada en lugar de en tiempo real. Entonces tu emulador puede tomar un LDA # 10, cargar un con inmediato, el emulador ve la carga Una instrucción inmediata, sabe que tiene que leer el siguiente byte que es el inmediato que el emulador tiene una variable en el código para el registro A y pone el valor inmediato en esa variable. Antes de completar las instrucciones, el emulador necesita actualizar las banderas, en este caso, la bandera de Cero es clara, la bandera de N es clara, C y V no se tocan.Pero, ¿y si la siguiente instrucción fuera una carga X inmediata? No es gran cosa, ¿verdad? Bueno, la carga x también modificará los indicadores z y n, por lo que la próxima vez que ejecutes la carga de una instrucción podrás darte cuenta de que no tienes que calcular las banderas porque serán destruidas, es un código muerto en la emulación. Usted puede continuar con este tipo de pensamiento, digamos que ve el código que copia la x de registro a la de un registro y luego empuja el un registro en la pila se copia a la y registro a la de un registro y lo empuja en la pila, podría reemplazar ese pedazo simplemente presionando los registros xey en la pila. O puede ver un par de agregar con acarreos encadenados para realizar un agregado de 16 bits y almacenar el resultado en ubicaciones de memoria adyacentes. Básicamente busca operaciones que el procesador que se está emulando no pudo hacer, pero es fácil de hacer en la emulación. La traducción binaria estática que sugiero que investigue antes de la recompilación dinámica, realiza este análisis y traducción de forma estática, como antes de ejecutar el código. En lugar de emular, puede traducir los códigos de operación a C, por ejemplo, y eliminar tanto código muerto como pueda (una buena característica es que el compilador de C puede eliminar más código muerto para usted).

Una vez que el concepto de la emulación y la traducción se entiende entonces se puede tratar de hacerlo de forma dinámica, desde luego, no es trivial. Sugiero tratar de hacer nuevamente una traducción estática de un código binario al procesador de la máquina del procesador de destino, lo cual es un buen ejercicio. No intentaría optimizaciones dinámicas de tiempo de ejecución hasta que hubiera tenido éxito en realizarlas estáticamente contra a/the binary.

virtualización es una historia diferente, usted está hablando acerca de cómo ejecutar el mismo procesador en el mismo procesador. Entonces x86 en un x86 por ejemplo. la belleza aquí es que al usar procesadores x86 no antiguos, puede tomar el programa que se está virtualizando y ejecutar los códigos de operación reales en el procesador real, sin emulación. Te atrapa de configuración integradas en el procesador para coger cosas, por lo que los valores de carga en AX y la adición de BX, etc., todo ocurre en tiempo real sobre el procesador, cuando AX quiere leer o escribir en la memoria depende de su mecanismo de interceptación si las direcciones se encuentran dentro las máquinas virtuales ram espacio, no hay trampas, pero digamos que el programa escribe en una dirección que es la UART virtualizado, usted tiene la trampa de procesador que a continuación, a continuación, VMware o lo que sea que decodifica escritura y emula que hablar con un puerto serie real. Sin embargo, esa instrucción no era en tiempo real, llevó bastante tiempo ejecutarla. Lo que podría hacer si elige es reemplazar esa instrucción o conjunto de instrucciones que escriben un valor en el puerto serie virtualizado y tal vez luego escribir en una dirección diferente que podría ser el puerto serie real o alguna otra ubicación que no va a funcionar. causa un error que hace que el administrador de vm tenga que emular la instrucción. O agregue un código en el espacio de memoria virtual que realiza una escritura en el uart sin una trampa, y haga que ese código se bifurque a esta rutina de escritura uart. La próxima vez que aciertes ese trozo de código, ahora se ejecuta en tiempo real.

Otra cosa que puede hacer es, por ejemplo, emular y, a medida que avanza, traducir a un bytcode intermedio virtual, como llvm. A partir de ahí, puede traducir de la máquina intermedia a la máquina nativa, reemplazando eventualmente grandes secciones del programa, si no todo. Todavía tiene que lidiar con los periféricos y E/S.

Cuestiones relacionadas