Dipende. Qualcosa compilato per IA-32 (Intel a 32 bit) potrebbe essere eseguito su amd64 poiché Linux su Intel mantiene la retrocompatibilità con le applicazioni a 32 bit (con software adeguato installato). Ecco il tuo code
compilato sul sistema RedHat 7.3 a 32 bit (circa 2002, gcc versione 2.96) e poi il binario copiato su ed eseguito su un sistema Centos 7.4 a 64 bit (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
L'antica RedHat da 7.3 a Centos 7.4 (essenzialmente RedHat Enterprise Linux 7.4) si trova nella stessa famiglia "distributiva", quindi probabilmente avrà una portabilità migliore rispetto a passare da un'installazione casuale "Linux da zero" dal 2002 ad un'altra distribuzione Linux casuale nel 2018 .
Qualcosa compilato per amd64 non funzionerebbe solo su versioni a 32 bit di Linux (il vecchio hardware non è a conoscenza del nuovo hardware). Ciò vale anche per i nuovi software compilati su sistemi moderni destinati a essere eseguiti su vecchie cose antiche, poiché le librerie e persino le chiamate di sistema potrebbero non essere portatili all'indietro, quindi potrebbero richiedere trucchi di compilazione o ottenere un vecchio compilatore e così via, o forse invece compilando sul vecchio sistema. (Questa è una buona ragione per tenere in giro macchine virtuali di vecchie cose antiche.)
L'architettura è importante; amd64 (o IA-32) è molto diverso da ARM o MIPS quindi il binario di uno di questi non dovrebbe funzionare su un altro. A livello di assembly la main
sezione del codice su IA-32 viene compilata tramite gcc -S code.c
a
main:
pushl %ebp
movl %esp,%ebp
movl $99,%eax
popl %ebp
ret
con cui un sistema amd64 è in grado di gestire (su un sistema Linux - OpenBSD, al contrario, su amd64 non supporta i binari a 32 bit; la retrocompatibilità con i vecchi archi lascia spazio agli aggressori, ad esempio CVE-2014-8866 e amici). Nel frattempo su un sistema MIPS big-endian main
invece compila per:
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
che un processore Intel non avrà idea di cosa fare e allo stesso modo per l'assemblaggio Intel su MIPS.
È possibile utilizzare QEMU o un altro emulatore per eseguire il codice esterno (forse molto, molto lentamente).
Però! Il tuo codice è un codice molto semplice, quindi avrà meno problemi di portabilità rispetto a qualsiasi altra cosa; i programmi in genere fanno uso di librerie che sono cambiate nel tempo (glibc, openssl, ...); per quelli potrebbe anche essere necessario installare versioni precedenti di varie librerie (ad esempio RedHat generalmente inserisce "compat" nel nome del pacchetto)
compat-glibc.x86_64 1:2.12-4.el7.centos
o forse preoccuparsi delle modifiche ABI (Application Binary Interface) per cose vecchie che usano glibc, o più recenti modifiche dovute a C ++ 11 o altre versioni di C ++. Si potrebbe anche compilare statico (aumentando notevolmente la dimensione binaria su disco) per cercare di evitare problemi con la libreria, anche se il fatto che qualche vecchio binario lo abbia fatto dipende dal fatto che la vecchia distribuzione Linux stia compilando quasi tutto dinamico (RedHat: yes) o no. D'altra parte, cose come patchelf
possono riattivare i binari dinamici (ELF, ma probabilmente non a.out
formattarli) per usare altre librerie.
Però! Essere in grado di eseguire un programma è una cosa, e in realtà fare qualcosa di utile con un'altra. I vecchi binari Intel a 32 bit possono avere problemi di sicurezza se dipendono da una versione di OpenSSL che ha in sé qualche problema di sicurezza orribile e non backport, oppure il programma potrebbe non essere in grado di negoziare affatto con i moderni server Web (come i moderni i server rifiutano i vecchi protocolli e le cifre del vecchio programma), oppure il protocollo SSH versione 1 non è più supportato, oppure ...