Jawaban:
Program yang dikompilasi biasa melakukan "berjalan langsung" pada CPU, tetapi sebuah program tidak berjalan dalam ruang hampa:
Banyak program bergantung pada pustaka ( DLLs
atau .so
pustaka) eksternal yang dimuat secara dinamis . Cara untuk menghubungkan mereka adalah dengan compiler / linker, dan setiap OS memiliki standar yang berbeda. Namun, ada juga program "yang terhubung secara statis" yang menyediakan semua kode mereka sendiri.
OS modern tidak memberikan kendali penuh komputer ke program yang sedang berjalan. Program bergantung pada "panggilan sistem" untuk i / o, akses ke perangkat keras, dan hal-hal seperti sinyal dan memasuki kondisi tidur. Layanan dan antarmuka yang tersedia ditentukan oleh OS. OS juga mengontrol bagian mana dari sistem (memori, register, interupsi) yang diizinkan untuk digunakan oleh program.
Program GUI juga harus bekerja melalui lingkungan pengguna grafis untuk menggambar dirinya sendiri di layar. Tapi Anda mungkin sudah memikirkan hal ini.
Untuk alasan ini, aplikasi independen OS harus bergantung pada "mesin virtual", seperti yang disediakan oleh runtime java. Yang terpenting, VM menyediakan antarmuka standar untuk sumber daya OS (i / o, sinyal, dll). Tentu saja, java atau python juga mengartikan "bytecode" alih-alih berurusan dengan kebiasaan set instruksi Intel; tapi itu cerita yang berbeda.
OS yang berbeda memiliki fungsi yang berbeda pula. Windows memiliki port penyelesaian I / O, Linux tidak. FreeBSD memiliki kqueue, Linux tidak. Linux memiliki futex, Windows tidak. Mereka juga memiliki cara berbeda untuk melakukan hal yang sama - parameter apa yang Anda berikan untuk membuka file? Pesanan apa yang mereka masukkan? Seberapa spesifik Anda menjalankan fungsi "buka file" sistem operasi?
Secara umum, program tidak kompatibel karena perbedaan dalam antarmuka biner aplikasi mereka (ABI) .
Bukankah program dijalankan langsung pada CPU?
TIDAK ! Itulah tugas sistem operasi, untuk mencegah aplikasi menjalankan "langsung" pada CPU. Biasanya, pada level terendah (yaitu OS API dibangun), sebuah aplikasi berinteraksi dengan kernel sistem operasi .
Apakah karena program yang dikompilasi sendiri perlu merujuk pustaka spesifik OS?
Ya . Banyak pustaka OS ditulis untuk memfasilitasi interfacing dengan sistem operasi itu sendiri, tetapi ada juga banyak yang ditulis sebagai cross-platform. Ini menyembunyikan antarmuka OS tingkat rendah dari pengembang, dan mengasumsikan versi yang dikompilasi untuk OS tersebut akan tersedia saat runtime (lihat di bawah).
Meskipun perpustakaan dapat ditulis secara lintas platform, ketika dikompilasi mereka tidak dapat dijalankan lintas platform. Mereka masih perlu dikompilasi ulang untuk sistem operasi target spesifik, sekali lagi untuk memanfaatkan komponen-komponen dasar yang mendasari sistem operasi (kernel).
Apa perbedaan antara program yang dikompilasi untuk satu OS vs yang lain?
Akhirnya, file yang dapat dieksekusi sendiri sering mengandung header pemuatan biner yang sangat spesifik dan sebagainya (mis. Format file PE Executable [.exe, .dll, dll ...] untuk Windows, atau ELF untuk Linux [tidak ada, .o, .so , dll ...]). Ini juga dapat mencakup kode untuk memuat binari yang dikompilasi OS spesifik untuk perpustakaan perangkat lunak tertentu.
Terakhir, dari perspektif programmer: konvensi pemanggilan . Kode yang dikompilasi meneruskan variabel ke fungsi dengan cara tertentu (yaitu melalui register, atau di stack) dalam urutan yang sangat khusus. Bahkan kemudian, juga harus disepakati siapa yang bertanggung jawab untuk "membersihkan" panggilan fungsi (penelepon atau callee?). Meskipun ada beberapa konvensi pemanggilan x86 standar dan banyak digunakan , beberapa mungkin tidak didukung oleh sistem operasi tertentu (ini adalah bagian dari ABI).