La respuesta breve : no puede traducir un ejecutable compilado y vinculado. Si bien es técnicamente posible, es altamente improbable lograrlo (ver más abajo). Sin embargo , si tiene el archivo fuente del ensamblado (que contiene las instrucciones y las etiquetas), es muy posible hacerlo (aunque si de alguna manera obtiene el origen del ensamblado, a menos que el programa esté escrito en ensamblado, debe tener el código fuente del programa original como bueno, para empezar sería mejor compilarlo para las diferentes arquitecturas).
La respuesta larga :
QEMU y otros emuladores pueden traducir las instrucciones sobre la marcha y, por lo tanto, ejecutar un ejecutable en una computadora para la que no se compiló. ¿Por qué no hacer esta traducción con anticipación, en lugar de hacerlo sobre la marcha para acelerar el proceso?
Sé que puede parecer fácil en principio, pero en la práctica, es casi imposible por algunas razones principales. Para comenzar, diferentes conjuntos de instrucciones utilizan modos de direccionamiento muy diferentes, diferentes estructuras de código de operación, diferentes tamaños de palabras, y algunos ni siquiera tienen las instrucciones que necesita.
Digamos que necesita reemplazar la instrucción XYZ
con dos instrucciones más, ABC
y DEF
. Ahora ha cambiado efectivamente todas las direcciones relativas / offset en todo el programa a partir de ese momento, por lo que necesitaría analizar y revisar todo el programa y actualizar las compensaciones (tanto antes como después del cambio). Ahora, supongamos que uno de los desplazamientos cambia significativamente: ahora debe cambiar los modos de direccionamiento, lo que podría cambiar el tamaño de la dirección. Esto nuevamente lo obligará a volver a escanear todo el archivo y volver a calcular todas las direcciones, y así sucesivamente.
Cuando escribe programas de ensamblaje, puede usar etiquetas, pero la CPU no: cuando se ensambla el archivo, todas las etiquetas se calculan como ubicaciones relativas, absolutas o desplazadas. Puede ver por qué esto se convierte rápidamente en una tarea no trivial y casi imposible. Reemplazar una sola instrucción puede requerir que pase por todo el programa cientos de veces antes de continuar.
Desde mi conocimiento algo limitado del ensamblaje, la mayoría de las instrucciones como MOV, ADD y otras deberían ser portátiles en todas las arquitecturas.
Sí, pero mira los problemas que describí anteriormente. ¿Qué pasa con el tamaño de palabra de la máquina? Longitud de la dirección? ¿Tiene incluso los mismos modos de direccionamiento? Una vez más, no puede simplemente "buscar y reemplazar" instrucciones. Cada segmento de un programa tiene una dirección definida específicamente. Los saltos a otras etiquetas se reemplazan con direcciones de memoria literales o desplazadas cuando se ensambla un programa.
Cualquier cosa que no tenga una asignación directa podría asignarse a algún otro conjunto de instrucciones, ya que todas las máquinas están Turing Complete. ¿Sería esto demasiado complicado? ¿No funcionaría en absoluto por alguna razón con la que no estoy familiarizado? ¿Funcionaría, pero no daría mejores resultados que usar un emulador?
Estás 100% en lo cierto al decir que es posible y sería mucho más rápido . Sin embargo, escribir un programa para lograr esto es increíblemente difícil y altamente improbable, si no es por nada, excepto por los problemas que describí anteriormente.
Si tuviera el código fuente del ensamblado real, sería trivial traducir el código de la máquina a otra arquitectura de conjunto de instrucciones. Sin embargo, el código de la máquina en sí está ensamblado , por lo que sin la fuente de ensamblaje (que contiene varias etiquetas utilizadas para calcular las direcciones de memoria), se vuelve increíblemente difícil. Nuevamente, cambiar una sola instrucción puede cambiar las compensaciones de memoria en todo el programa y requerir cientos de pases para volver a calcular las direcciones.
Hacer esto para un programa con unos pocos miles de instrucciones requeriría decenas, si no cientos de miles de pases. Para programas relativamente pequeños, esto puede ser posible, pero recuerde que el número de pasadas aumentará exponencialmente con el número de instrucciones de la máquina en el programa. Para cualquier programa de un tamaño suficientemente decente, es casi imposible.