Це залежить. Щось, складене для 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 (бінарний інтерфейс програми) для старих речей, які використовують glibc, або останніх змін через C ++ 11 або інших C ++ випусків. Можна також компілювати статичні (значно збільшуючи бінарний розмір на диску), щоб спробувати уникнути проблем із бібліотекою, хоча від того, чи робив це якийсь старий бінарний файл, залежить від того, чи використовував старий дистрибутив Linux більшість всього динамічного (RedHat: так) чи ні. З іншого боку, такі речі patchelf
можуть перенаправляти динамічні (ELF, але, мабуть, не a.out
форматування) бінарні файли для використання інших бібліотек.
Однак! Вміти запускати програму - це одне, а насправді робити щось корисне з нею інше. У старих 32-розрядних бінарних файлів Intel можуть виникнути проблеми із безпекою, якщо вони залежать від версії OpenSSL, яка має якусь жахливу і непідтримувану проблему безпеки, або програма взагалі не зможе домовитись із сучасними веб-серверами (як сучасний сервери відхиляють старі протоколи та шифри старої програми), або протокол SSH версії 1 більше не підтримується, або ...