Si te refieres a convertir un ejecutable binario, es factible, pero no es fácil.
Es más fácil en arquitecturas de instrucciones de longitud fija - lo que significa: no Intel. Esto se debe a que es muy fácil recorrer el código y averiguar qué partes son instrucciones, y qué partes son datos.
En realidad es más fácil proporcionar una capa de compatibilidad, si, cuando en el modo de 64 bits, la CPU es capaz de ejecutar procesos individuales en el modo de 32 bits.
También se puede hacer lo que se llama "recompilación dinámica" del código binario. Así es como Rosetta fue capaz de permitir que los binarios de PowerPC Mac OS X se ejecuten en Intel Mac OS X hasta Mac OS X antes de Leopard (en realidad los tenía funcionando en Leopard, en mi oficina, pero B&I no quería mantener archivos binarios separados).
Alternativamente, puede emular el entorno de ejecución de 32 bits utilizando un programa emulador; para Intel, esto probablemente sería QEMU o algo similar.
Si se trata de código fuente, es más fácil y más difícil a la vez.
Puede recompilar el código fuente con un compilador que tenga como objetivo el entorno de ejecución de 64, en lugar del entorno de ejecución de 32 bits.
Esto le llevará parte del camino; por desgracia, no le llevará todo el camino, ya que una gran cantidad de código hace suposiciones sobre los tamaños de los tipos de datos. Uno bastante común es la conversión entre puntero e int, int y long, y promociones y degradaciones de tipo similares.
Estos pueden resultar en una pérdida de datos, una pérdida de precisiones, o errores rotundos en el código - por ejemplo, el código que se utiliza para representar campos de bits y otros datos, que ahora es el tamaño incorrecto.
También está el problema de los datos externos.
This is most obvious in networking, since the structures passed back and forth as packets tend to have very strict field size requirements.
You can also have a problem with external data prepresentation; if you saved something out as a:
- struct foo {
- long i;
- char str[20];
- ...
- };
This will not have the same on disk representation in ILP32 (Integer, Long, and Pointer are 32 bits) and LP64 (Integer is 32 bits; Long and Pointer are 64 bits).
ILP32 and LP64 are the most common ways of implementing 32 vs. 64 bit data types in most computer language implementation; there are actually other possibilities, which are less commonly used.
Además, hay problemas entre las compilaciones de 32 y 64 bits que rodean el empaquetamiento de la estructura (cuánto espacio se asigna para llegar a un límite de alineación interno de la estructura) y el relleno de la estructura (cuánto espacio se asigna al final de la estructura, de tal manera que, en una matriz de estructuras, el 0º y el 1º elemento tienen los mismos límites de alineación), y así sucesivamente.
Hay herramientas para automatizar gran parte de este trabajo; la más grande es habilitar todas las advertencias de conversión de tipo y de tamaño en su compilador, y hacer que sean errores. Pero también hay herramientas de análisis estático, y hay herramientas de análisis de código objeto (binarios con símbolos, no necesariamente ejecutables, sino mínimamente: unidades de compilación).
En resumen, cualquiera de los dos tipos de conversión puede suponer un gran esfuerzo para conseguirlo*.
(*) Sí, he hecho esto múltiples veces, y en múltiples arquitecturas, a lo largo de mi carrera.