По-разному. Что-то скомпилированное для IA-32 (32-разрядная версия Intel) может работать на amd64, поскольку Linux на Intel сохраняет обратную совместимость с 32-разрядными приложениями (с установленным подходящим программным обеспечением). Вот ваш code
скомпилированный в 32-битной системе RedHat 7.3 (около 2002 года, gcc версии 2.96), а затем скопированный двоичный файл в 64-битную систему Centos 7.4 и его запуск (около 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
Древние RedHat 7.3 - Centos 7.4 (по сути RedHat Enterprise Linux 7.4) остаются в том же семействе «дистрибутивов», поэтому, вероятно, будут иметь лучшую переносимость, чем переход от какой-то случайной установки «Linux с нуля» с 2002 года к другому случайному дистрибутиву Linux в 2018 году ,
То, что скомпилировано для amd64, не будет работать только на 32-битных выпусках Linux (старое оборудование не знает о новом оборудовании). Это также относится к новому программному обеспечению, скомпилированному на современных системах, предназначенных для запуска на древних старых объектах, поскольку библиотеки и даже системные вызовы могут не иметь обратной переносимости, поэтому могут потребоваться приемы компиляции, или получить старый компилятор и т. Д., Или, возможно, вместо этого компиляция по старой системе. (Это хорошая причина, чтобы хранить виртуальные машины древних старых вещей вокруг.)
Архитектура имеет значение; amd64 (или IA-32) сильно отличается от ARM или MIPS, поэтому двоичный файл одного из них не должен работать на другом. На сборку нивелировать main
часть вашего кода на IA-32 компиляций с помощью gcc -S code.c
к
main:
pushl %ebp
movl %esp,%ebp
movl $99,%eax
popl %ebp
ret
с которой может справиться система amd64 (в системе Linux - OpenBSD, в отличие от amd64 , не поддерживает 32-разрядные двоичные файлы; обратная совместимость со старыми архивами дает возможность злоумышленникам, например CVE-2014-8866 и друзьям). Между тем в системе MIPS с прямым порядком байтов main
вместо этого компилируется в:
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
с которым процессор Intel понятия не имеет, что делать, и аналогично для сборки Intel на MIPS.
Вы можете использовать QEMU или другой эмулятор для запуска стороннего кода (возможно, очень, очень медленно).
Тем не мение! Ваш код очень простой, поэтому у него будет меньше проблем с переносимостью, чем с чем-либо еще; программы обычно используют библиотеки, которые со временем менялись (glibc, openssl, ...); для них также может потребоваться установка более старых версий различных библиотек (например, RedHat обычно помещает «compat» где-то в имени пакета)
compat-glibc.x86_64 1:2.12-4.el7.centos
или, возможно, беспокоиться об изменениях ABI (Application Binary Interface) для старых вещей, которые используют glibc, или о более недавних изменениях из-за C ++ 11 или других выпусков C ++. Можно также скомпилировать static (значительно увеличив бинарный размер на диске), чтобы попытаться избежать проблем с библиотеками, хотя от того, делал ли какой-нибудь старый двоичный файл это, зависит, компилирует ли старый дистрибутив большинство всего динамического (RedHat: да) или нет. С другой стороны, такие вещи patchelf
могут перенастраивать динамические (ELF, но, вероятно, не a.out
отформатированные) двоичные файлы для использования других библиотек.
Тем не мение! Возможность запустить программу - это одно, а на самом деле делать что-то полезное с этим - другое. Старые 32-разрядные двоичные файлы Intel могут иметь проблемы с безопасностью, если они зависят от версии OpenSSL, в которой есть какая-то ужасная проблема безопасности, о которой не сообщалось в бэкпорте, или программа может вообще не иметь возможности вести переговоры с современными веб-серверами (как современные серверы отклоняют старые протоколы и шифры старой программы), или протокол SSH версии 1 больше не поддерживается, или ...