Depende. Algo compilado para IA-32 (Intel de 32 bits) puede ejecutarse en amd64 ya que Linux en Intel conserva la compatibilidad con las aplicaciones de 32 bits (con el software adecuado instalado). Aquí está code
compilado en el sistema RedHat 7.3 de 32 bits (circa 2002, gcc versión 2.96) y luego el binario copiado y ejecutado en un sistema Centos 7.4 de 64 bits (circa 2017):
-bash-4.2$ file code
code: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped
-bash-4.2$ ./code
-bash: ./code: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
-bash-4.2$ sudo yum -y install glibc.i686
...
-bash-4.2$ ./code ; echo $?
99
Ancient RedHat 7.3 a Centos 7.4 (esencialmente RedHat Enterprise Linux 7.4) se mantiene en la misma familia de "distribución", por lo que probablemente tendrá una mejor portabilidad que pasar de una instalación aleatoria "Linux desde cero" de 2002 a otra distribución aleatoria de Linux en 2018 .
Algo compilado para amd64 no se ejecutaría en versiones de Linux de solo 32 bits (el hardware antiguo no conoce el hardware nuevo). Esto también es cierto para el nuevo software compilado en sistemas modernos destinados a ejecutarse en cosas antiguas y antiguas, ya que las bibliotecas e incluso las llamadas al sistema pueden no ser portátiles hacia atrás, por lo que pueden requerir trucos de compilación u obtener un compilador antiguo, etc. compilando en el viejo sistema. (Esta es una buena razón para mantener las máquinas virtuales de cosas antiguas antiguas).
La arquitectura sí importa; amd64 (o IA-32) es muy diferente de ARM o MIPS, por lo que no se esperaría que el binario de uno de ellos se ejecute en otro. En el nivel de ensamblaje, la main
sección de su código en IA-32 se compila a través gcc -S code.c
de
main:
pushl %ebp
movl %esp,%ebp
movl $99,%eax
popl %ebp
ret
que un sistema amd64 puede manejar (en un sistema Linux, OpenBSD, por el contrario, en amd64 no admite binarios de 32 bits; la compatibilidad con versiones anteriores con arcos antiguos les da a los atacantes margen de maniobra, por ejemplo, CVE-2014-8866 y amigos). Mientras tanto, en un sistema MIPS big-endian en su main
lugar se compila para:
main:
.frame $fp,8,$31
.mask 0x40000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-8
sw $fp,4($sp)
move $fp,$sp
li $2,99
move $sp,$fp
lw $fp,4($sp)
addiu $sp,$sp,8
j $31
nop
con el que un procesador Intel no tendrá idea de qué hacer, y tampoco para el ensamblaje Intel en MIPS.
Posiblemente podría usar QEMU o algún otro emulador para ejecutar código extranjero (quizás muy, muy lentamente).
¡Sin embargo! Su código es muy simple, por lo que tendrá menos problemas de portabilidad que cualquier otra cosa; los programas suelen utilizar bibliotecas que han cambiado con el tiempo (glibc, openssl, ...); para aquellos que también pueden necesitar instalar versiones anteriores de varias bibliotecas (RedHat, por ejemplo, generalmente coloca "compat" en algún lugar del nombre del paquete para tales)
compat-glibc.x86_64 1:2.12-4.el7.centos
o posiblemente preocuparse por los cambios de ABI (Application Binary Interface) para cosas viejas que usan glibc, o cambios más recientes debido a C ++ 11 u otras versiones de C ++. También se podría compilar estática (aumentando enormemente el tamaño binario en el disco) para tratar de evitar problemas de biblioteca, aunque si algún binario antiguo hizo esto depende de si la distribución Linux anterior estaba compilando casi todo lo dinámico (RedHat: sí) o no. Por otro lado, cosas como patchelf
pueden reiniciar binarios dinámicos (ELF, pero probablemente no a.out
formatear) para usar otras bibliotecas.
¡Sin embargo! Poder ejecutar un programa es una cosa, y hacer algo útil con él es otra. Los viejos binarios de Intel de 32 bits pueden tener problemas de seguridad si dependen de una versión de OpenSSL que tiene algún problema de seguridad horrible y no respaldado, o el programa puede no ser capaz de negociar con servidores web modernos (como los modernos los servidores rechazan los protocolos y cifrados antiguos del programa antiguo), o el protocolo SSH versión 1 ya no es compatible, o ...