Nó phụ thuộc. Một cái gì đó được biên dịch cho IA-32 (Intel 32 bit) có thể chạy trên amd64 vì Linux trên Intel vẫn giữ được khả năng tương thích ngược với các ứng dụng 32 bit (đã cài đặt phần mềm phù hợp). Đây là bản code
tổng hợp của bạn trên hệ thống RedHat 7.3 32 bit (khoảng năm 2002, gcc phiên bản 2.96) và sau đó nhị phân được sao chép sang và chạy trên hệ thống Centos 7.4 64 bit (khoảng năm 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 đến Centos 7.4 (về cơ bản là RedHat Enterprise Linux 7.4) đang ở trong cùng một gia đình "phân phối", do đó có thể sẽ có tính di động tốt hơn so với việc cài đặt "Linux từ đầu" ngẫu nhiên từ năm 2002 sang một bản phân phối Linux ngẫu nhiên khác vào năm 2018 .
Một cái gì đó được biên dịch cho amd64 sẽ không chạy trên các bản phát hành Linux 32 bit (phần cứng cũ không biết về phần cứng mới). Điều này cũng đúng với phần mềm mới được biên dịch trên các hệ thống hiện đại dự định chạy trên những thứ cũ kỹ, vì các thư viện và thậm chí các cuộc gọi hệ thống có thể không di động được, do đó có thể yêu cầu các thủ thuật biên dịch, hoặc có được trình biên dịch cũ, v.v. biên dịch trên hệ thống cũ. (Đây là một lý do tốt để giữ các máy ảo của những thứ cổ xưa xung quanh.)
Kiến trúc có vấn đề; amd64 (hoặc IA-32) khác rất nhiều so với ARM hoặc MIPS, do đó, nhị phân từ một trong số đó sẽ không được mong đợi chạy trên một cái khác. Ở cấp lắp ráp các main
phần của mã của bạn trên IA-32 biên dịch thông qua gcc -S code.c
để
main:
pushl %ebp
movl %esp,%ebp
movl $99,%eax
popl %ebp
ret
mà một hệ thống amd64 có thể xử lý (trên hệ thống Linux - OpenBSD ngược lại với amd64 không hỗ trợ nhị phân 32 bit; khả năng tương thích ngược với các vòm cũ sẽ tạo cho kẻ tấn công ngọ nguậy, ví dụ CVE-2014-8866 và bạn bè). Trong khi đó, trên một hệ thống MIPS cuối lớn main
thay vì biên dịch thành:
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
mà bộ xử lý Intel sẽ không biết phải làm gì và tương tự như vậy đối với lắp ráp Intel trên MIPS.
Bạn có thể có thể sử dụng QEMU hoặc một số trình giả lập khác để chạy mã nước ngoài (có lẽ rất, rất chậm).
Tuy nhiên! Mã của bạn là mã rất đơn giản, do đó sẽ có ít vấn đề về tính di động hơn bất kỳ thứ gì khác; các chương trình thường sử dụng các thư viện đã thay đổi theo thời gian (glibc, openssl, ...); đối với những người cũng có thể cần cài đặt các phiên bản cũ hơn của các thư viện khác nhau (ví dụ RedHat thường đặt "compat" ở đâu đó trong tên gói như vậy)
compat-glibc.x86_64 1:2.12-4.el7.centos
hoặc có thể lo lắng về các thay đổi ABI (Giao diện nhị phân ứng dụng) để biết những thứ cũ sử dụng glibc hoặc những thay đổi gần đây do C ++ 11 hoặc các bản phát hành C ++ khác. Người ta cũng có thể biên dịch tĩnh (tăng đáng kể kích thước nhị phân trên đĩa) để cố gắng tránh các sự cố thư viện, mặc dù một số nhị phân cũ có làm điều này hay không phụ thuộc vào việc bản phân phối Linux cũ có biên dịch hầu hết mọi thứ động hay không (RedHat: yes) hay không. Mặt khác, những thứ như patchelf
có thể kích hoạt lại các a.out
nhị phân động (ELF, nhưng có thể không định dạng) để sử dụng các thư viện khác.
Tuy nhiên! Có thể chạy một chương trình là một chuyện, và thực sự làm một cái gì đó hữu ích với nó khác. Các tệp nhị phân Intel 32 bit cũ có thể có vấn đề về bảo mật nếu chúng phụ thuộc vào phiên bản OpenSSL có vấn đề bảo mật khủng khiếp và không được hỗ trợ trong đó, hoặc chương trình có thể không thể đàm phán với tất cả các máy chủ web hiện đại (như hiện đại máy chủ từ chối các giao thức và mật mã cũ của chương trình cũ) hoặc giao thức SSH phiên bản 1 không còn được hỗ trợ hoặc ...