Mengapa OS perangkat lunak spesifik?

77

Saya mencoba menentukan rincian teknis mengapa perangkat lunak diproduksi menggunakan bahasa pemrograman untuk sistem operasi tertentu hanya bekerja dengan mereka.

Ini adalah pemahaman saya bahwa binari khusus untuk prosesor tertentu karena bahasa mesin khusus prosesor yang mereka pahami dan set instruksi yang berbeda antara prosesor yang berbeda. Tetapi dari mana datangnya kekhususan sistem operasi? Saya dulu menganggap itu adalah API yang disediakan oleh OS tapi kemudian saya melihat diagram ini dalam sebuah buku: Diagram

Sistem Operasi - Internal dan Prinsip-prinsip Desain edisi ke-7 - W. Stallings (Pearson, 2012)

Seperti yang Anda lihat, API tidak diindikasikan sebagai bagian dari sistem operasi.

Jika misalnya saya membuat program sederhana dalam C menggunakan kode berikut:

#include<stdio.h>

main()
{
    printf("Hello World");

}

Apakah kompiler melakukan sesuatu yang spesifik OS saat kompilasi ini?

pengguna139929
sumber
15
Apakah Anda mencetak ke jendela? atau konsol? atau ke memori grafis? Bagaimana Anda menyimpan data di sana? Melihat printf untuk Apple] [+ akan berbeda dengan Mac OS 7 dan sekali lagi sangat berbeda dari Mac OS X (hanya menggunakan satu 'baris' komputer).
3
Karena jika Anda menulis kode itu untuk Mac OS 7, itu akan muncul dalam teks di jendela baru. Jika Anda melakukannya di Apple] [+, itu akan menulis ke beberapa segmen memori secara langsung. Pada Mac OS X, ia menuliskannya ke konsol. Jadi, itulah tiga cara penulisan penanganan kode yang didasarkan pada perangkat keras eksekusi yang ditangani oleh lapisan pustaka.
2
@StevenBurnap yep - en.wikipedia.org/wiki/Aztec_C
10
Fungsi FFT Anda akan dengan senang hati berjalan di bawah Windows atau Linux (pada CPU yang sama), bahkan tanpa kompilasi ulang. Tetapi bagaimana Anda akan menampilkan hasilnya? Menggunakan API sistem operasi, tentu saja. ( printfdari msvcr90.dll tidak sama dengan printfdari libc.so.6)
user253751
9
Bahkan jika API "bukan bagian dari sistem operasi", mereka masih berbeda jika Anda berpindah dari satu OS ke OS lainnya. (Yang, tentu saja, menimbulkan pertanyaan tentang apa arti frasa "bukan bagian dari sistem operasi", menurut diagram.)
Theodoros Chatzigiannakis

Jawaban:

78

Anda menyebutkan bagaimana jika kode tersebut khusus untuk CPU, mengapa harus spesifik juga untuk OS. Ini sebenarnya lebih merupakan pertanyaan menarik yang diasumsikan oleh banyak jawaban di sini.

Model Keamanan CPU

Program pertama berjalan di sebagian besar arsitektur CPU berjalan di dalam apa yang disebut cincin dalam atau cincin 0 . Bagaimana lengkung CPU spesifik menerapkan dering berbeda-beda, tetapi hampir setiap CPU modern memiliki setidaknya 2 mode operasi, yang istimewa dan menjalankan kode 'bare metal' yang dapat melakukan operasi legal apa pun yang dapat dilakukan CPU dan yang lainnya adalah tidak dipercaya dan menjalankan kode terproteksi yang hanya dapat melakukan serangkaian kemampuan aman yang ditentukan. Namun beberapa CPU memiliki granularitas yang jauh lebih tinggi dan untuk menggunakan VM aman setidaknya 1 atau 2 cincin tambahan diperlukan (sering diberi label dengan angka negatif) namun ini berada di luar cakupan jawaban ini.

Di mana OS masuk

OS penugasan tunggal awal

Dalam DOS yang sangat awal dan sistem berbasis tugas tunggal lainnya awal semua kode dijalankan di cincin bagian dalam, setiap program yang pernah Anda jalankan memiliki kekuatan penuh atas seluruh komputer dan dapat melakukan apa saja jika terjadi kesalahan termasuk menghapus semua data Anda atau bahkan melakukan kerusakan perangkat keras dalam beberapa kasus ekstrem seperti mengatur mode tampilan yang tidak valid pada layar tampilan yang sangat lama, lebih buruk, ini bisa disebabkan oleh kode kereta yang sederhana tanpa ada niat jahat apa pun.

Kode ini sebenarnya sebagian besar OS agnostik, selama Anda memiliki loader yang mampu memuat program ke dalam memori (cukup sederhana untuk format biner awal) dan kode tersebut tidak bergantung pada driver apa pun, menerapkan semua akses perangkat keras itu sendiri yang harus dijalankan di bawah OS apa pun asalkan dijalankan di ring 0. Catatan, OS yang sangat sederhana seperti ini biasanya disebut monitor jika hanya digunakan untuk menjalankan program lain dan tidak menawarkan fungsionalitas tambahan.

OS multi-tasking modern

Sistem operasi yang lebih modern termasuk UNIX , versi Windows dimulai dengan NT dan berbagai OS lain yang sekarang tidak jelas memutuskan untuk memperbaiki situasi ini, pengguna menginginkan fitur tambahan seperti multitasking sehingga mereka dapat menjalankan lebih dari satu aplikasi sekaligus dan perlindungan, sehingga bug ( atau kode jahat) dalam suatu aplikasi tidak lagi dapat menyebabkan kerusakan tak terbatas pada mesin dan data.

Ini dilakukan dengan menggunakan cincin yang disebutkan di atas, OS akan mengambil satu-satunya tempat berjalan di cincin 0 dan aplikasi akan berjalan di cincin luar yang tidak dipercaya, hanya dapat melakukan serangkaian operasi terbatas yang diizinkan oleh OS.

Namun peningkatan utilitas dan perlindungan ini berbayar, program sekarang harus bekerja dengan OS untuk melakukan tugas-tugas yang tidak boleh mereka lakukan sendiri, mereka tidak bisa lagi mengambil kendali langsung atas hard disk dengan mengakses memori dan mengubah sewenang-wenang. data, sebaliknya mereka harus meminta OS untuk melakukan tugas-tugas ini untuk mereka sehingga dapat memeriksa bahwa mereka diizinkan untuk melakukan operasi, tidak mengubah file yang bukan milik mereka, itu juga akan memeriksa bahwa operasi itu memang sah dan tidak akan meninggalkan perangkat keras dalam keadaan tidak terdefinisi.

Setiap OS memutuskan implementasi yang berbeda untuk perlindungan ini, sebagian berdasarkan arsitektur tempat OS dirancang dan sebagian didasarkan pada desain dan prinsip-prinsip OS yang dimaksud, UNIX misalnya menempatkan fokus pada mesin yang baik untuk penggunaan multi-pengguna dan fokus fitur yang tersedia untuk ini sementara windows dirancang agar lebih sederhana, untuk berjalan pada perangkat keras yang lebih lambat dengan satu pengguna. Cara program ruang-pengguna juga berbicara dengan OS sangat berbeda pada X86 seperti pada ARM atau MIPS misalnya, memaksa OS multi-platform untuk membuat keputusan berdasarkan kebutuhan untuk bekerja pada perangkat keras yang ditargetkan untuknya.

Interaksi spesifik OS ini biasanya disebut "pemanggilan sistem" dan mencakup bagaimana program ruang pengguna berinteraksi dengan perangkat keras melalui OS sepenuhnya, mereka pada dasarnya berbeda berdasarkan fungsi OS dan dengan demikian sebuah program yang melakukan tugasnya melalui pemanggilan sistem perlu menjadi spesifik OS.

Program Loader

Selain panggilan sistem, setiap OS menyediakan metode berbeda untuk memuat program dari media penyimpanan sekunder dan ke dalam memori , agar dapat dimuat oleh OS tertentu, program harus berisi header khusus yang menjelaskan kepada OS bagaimana mungkin dimuat dan dijalankan.

Header ini dulunya cukup sederhana sehingga menulis loader untuk format yang berbeda hampir sepele, namun dengan format modern seperti elf yang mendukung fitur-fitur canggih seperti penghubung dinamis dan deklarasi lemah, sekarang hampir mustahil bagi OS untuk mencoba memuat binari. yang tidak dirancang untuk itu, ini berarti, bahkan jika tidak ada ketidakcocokan system call, sangat sulit untuk bahkan menempatkan program dalam ram dengan cara yang dapat dijalankan.

Perpustakaan

Namun, program jarang menggunakan pemanggilan sistem secara langsung, mereka hampir secara eksklusif mendapatkan fungsionalitasnya meskipun pustaka yang membungkus pemanggilan sistem dalam format yang sedikit lebih ramah untuk bahasa pemrograman, misalnya, C memiliki Perpustakaan Standar C dan glibc di Linux dan sejenisnya dan win32 lib di bawah Windows NT dan di atas, sebagian besar bahasa pemrograman lain juga memiliki pustaka yang serupa yang membungkus fungsionalitas sistem dengan cara yang tepat.

Pustaka-pustaka ini sampai taraf tertentu bahkan dapat mengatasi masalah lintas platform seperti dijelaskan di atas, ada sejumlah pustaka yang dirancang untuk menyediakan platform yang seragam untuk aplikasi sambil secara internal mengelola panggilan ke berbagai OS seperti SDL , ini berarti bahwa meskipun program tidak bisa kompatibel dengan biner, program yang menggunakan pustaka ini dapat memiliki sumber yang sama antar platform, membuat porting sesederhana kompilasi ulang.

Pengecualian atas

Terlepas dari semua yang saya katakan di sini, ada upaya untuk mengatasi keterbatasan karena tidak dapat menjalankan program di lebih dari satu sistem operasi. Beberapa contoh yang baik adalah proyek Wine yang telah berhasil ditiru baik win32 program loader, format biner dan pustaka sistem yang memungkinkan program Windows untuk berjalan di berbagai UNIX. Ada juga lapisan kompatibilitas yang memungkinkan beberapa sistem operasi BSD UNIX untuk menjalankan perangkat lunak Linux dan tentu saja Apple sendiri memungkinkan seseorang untuk menjalankan perangkat lunak MacOS lama di bawah MacOS X.

Namun proyek-proyek ini bekerja melalui tingkat besar upaya pengembangan manual. Bergantung pada seberapa berbedanya kedua OS tersebut, tingkat kesulitannya berkisar dari shim yang cukup kecil hingga hampir menyelesaikan emulasi OS lain yang seringkali lebih kompleks daripada menulis seluruh sistem operasi itu sendiri sehingga ini merupakan pengecualian dan bukan aturannya.

Vality
sumber
6
+1 "Mengapa OS perangkat lunak spesifik?" Karena sejarah.
Paul Draper
2
Apakah model keamanan CPU berasal-x86? mengapa dan kapan model ditemukan?
n611x007
8
@naxa Tidak, itu sudah lama sebelum x86, itu pertama kali diimplementasikan sebagian untuk Multics pada tahun 1969 yang merupakan OS pertama dengan fitur berbagi waktu yang berguna multi-pengguna yang membutuhkan model ini di komputer GE-645 , namun implementasi ini tidak lengkap dan bergantung pada dukungan perangkat lunak, implementasi lengkap dan aman pertama dalam perangkat keras adalah penerusnya, Honeywell 6180 . Ini sepenuhnya berbasis perangkat keras dan memungkinkan Multics untuk menjalankan kode dari beberapa pengguna tanpa kesempatan untuk saling campur tangan.
Vality
@ Vality Juga, IBM LPAR adalah ~ 1972.
Elliott Frisch
@ElliottFrisch wow, itu mengesankan. Saya tidak menyadari bahwa itu terlalu dini. Terima kasih atas info itu.
Vality
48

Seperti yang Anda lihat, API tidak diindikasikan sebagai bagian dari sistem operasi.

Saya pikir Anda terlalu banyak membaca diagram. Ya, OS akan menentukan antarmuka biner untuk bagaimana fungsi sistem operasi dipanggil, dan juga akan menentukan format file untuk executable, tetapi juga akan menyediakan API, dalam arti menyediakan katalog fungsi yang dapat dipanggil oleh aplikasi untuk memanggil layanan OS.

Saya pikir diagram hanya mencoba untuk menekankan bahwa fungsi sistem operasi biasanya dipanggil melalui mekanisme yang berbeda dari panggilan perpustakaan sederhana. Sebagian besar OS yang biasa digunakan prosesor menginterupsi untuk mengakses fungsi OS. Sistem operasi modern yang khas tidak akan membiarkan program pengguna secara langsung mengakses perangkat keras apa pun . Jika Anda ingin menulis karakter ke konsol, Anda harus meminta OS untuk melakukannya untuk Anda. Panggilan sistem yang digunakan untuk menulis ke konsol akan bervariasi dari OS ke OS, jadi di sana ada satu contoh mengapa perangkat lunak spesifik untuk OS.

printf adalah fungsi dari perpustakaan run time C dan dalam implementasi khas adalah fungsi yang cukup kompleks. Jika Anda google Anda dapat menemukan sumber untuk beberapa versi online. Lihat halaman ini untuk tur yang dipandu . Turun di rumput meskipun akhirnya membuat satu atau lebih panggilan sistem, dan masing-masing panggilan sistem khusus untuk sistem operasi host.

Charles E. Grant
sumber
4
Bagaimana jika semua program lakukan adalah menambahkan dua angka, tanpa input atau output. Apakah program itu masih spesifik OS?
Paul
2
OS dimaksudkan untuk meletakkan sebagian besar barang khusus perangkat keras di belakang / dalam lapisan abstraksi. Namun, OS itu sendiri (abstraksi) dapat berbeda dari implementasi ke implementasi. Ada POSIX beberapa OS (lebih atau kurang) mematuhi dan mungkin beberapa OS tetapi keseluruhan OS hanya berbeda terlalu banyak di bagian "terlihat" mereka dari abstraksi. Seperti yang dikatakan sebelumnya: Anda tidak dapat membuka / home / pengguna di windows dan Anda tidak dapat mengakses HKEY_LOCAL_MACHINE \ ... pada sistem * N * X. Anda dapat menulis perangkat lunak virtual ("emulasi") untuk ini untuk membantu mendekatkan sistem ini tetapi itu akan selalu menjadi "pihak ke-3" (dari OS POV).
RobIII
16
@ Paul Ya. Secara khusus, cara itu dikemas ke dalam executable akan menjadi OS-spesifik.
OrangeDog
4
@TimSeguine Saya tidak setuju dengan contoh Anda XP vs 7. Banyak pekerjaan yang dilakukan oleh Microsoft untuk memastikan API yang sama ada di 7 seperti di XP. Jelas apa yang terjadi di sini adalah bahwa program dirancang untuk dijalankan terhadap API atau kontrak tertentu. OS baru hanya mematuhi API / kontrak yang sama. Namun dalam hal windows API itu sangat eksklusif, itulah sebabnya tidak ada vendor OS lain yang mendukungnya. Meski begitu ada banyak contoh program yang TIDAK berjalan pada 7.
ArTs
3
@ Paul: Program yang tidak memiliki Input / Output adalah program kosong , yang harus dikompilasi ke no-op.
Bergi
14

Apakah kompiler melakukan sesuatu yang spesifik OS saat kompilasi ini?

Mungkin. Pada titik tertentu selama proses kompilasi dan penautan, kode Anda diubah menjadi biner khusus OS dan ditautkan dengan pustaka yang diperlukan. Program Anda harus disimpan dalam format yang diharapkan oleh sistem operasi sehingga OS dapat memuat program dan mulai menjalankannya. Selanjutnya, Anda memanggil fungsi pustaka standar printf(), yang pada tingkat tertentu diimplementasikan dalam hal layanan yang disediakan sistem operasi.

Perpustakaan menyediakan antarmuka - lapisan abstraksi dari sistem operasi dan perangkat keras - dan itu memungkinkan untuk mengkompilasi ulang program Anda untuk sistem operasi yang berbeda atau perangkat keras yang berbeda. Tapi abstraksi itu ada di tingkat sumber - setelah program dikompilasi dan ditautkan, itu terhubung ke implementasi spesifik dari antarmuka yang khusus untuk OS yang diberikan.

Caleb
sumber
12

Ada sejumlah alasan, tetapi satu alasan yang sangat penting adalah bahwa Sistem Operasi harus tahu cara membaca serangkaian byte yang menyusun program Anda ke dalam memori, menemukan perpustakaan yang pergi dengan program itu dan memuatnya ke dalam memori, dan kemudian mulai jalankan kode program Anda. Untuk melakukan ini, pencipta OS membuat format tertentu untuk rangkaian byte tersebut sehingga kode OS tahu ke mana harus mencari berbagai bagian struktur program Anda. Karena Sistem Operasi utama memiliki penulis yang berbeda, format ini sering tidak ada hubungannya satu sama lain. Secara khusus, format yang dapat dieksekusi Windows memiliki sedikit kesamaan dengan format ELF yang digunakan sebagian besar varian Unix. Jadi semua ini memuat, menghubungkan dinamis dan mengeksekusi kode harus spesifik OS.

Selanjutnya, setiap OS menyediakan satu set pustaka yang berbeda untuk berbicara dengan lapisan perangkat keras. Ini adalah API yang Anda sebutkan, dan umumnya perpustakaan yang menyajikan antarmuka yang lebih sederhana kepada pengembang sambil menerjemahkannya ke panggilan yang lebih kompleks dan lebih spesifik ke kedalaman OS itu sendiri, panggilan ini sering kali tidak berdokumen atau diamankan. Lapisan ini seringkali berwarna abu-abu, dengan API "OS" yang lebih baru dibangun sebagian atau seluruhnya pada API yang lebih lama. Sebagai contoh, di Windows, banyak API baru yang telah dibuat Microsoft selama bertahun-tahun pada dasarnya adalah lapisan di atas API Win32 asli.

Masalah yang tidak muncul dalam contoh Anda, tapi itu adalah salah satu yang lebih besar yang dihadapi pengembang adalah antarmuka dengan manajer jendela, untuk menyajikan GUI. Apakah window manager adalah bagian dari "OS" kadang-kadang tergantung pada sudut pandang Anda, serta OS itu sendiri, dengan GUI di Windows yang terintegrasi dengan OS pada tingkat yang lebih dalam, sedangkan GUI di Linux dan OS X sedang lebih dipisahkan secara langsung. Ini sangat penting karena saat ini apa yang orang biasa sebut "Sistem Operasi" adalah binatang yang jauh lebih besar daripada apa yang cenderung dijelaskan oleh buku teks, karena mencakup banyak komponen komponen aplikasi.

Akhirnya, bukan semata-mata masalah OS, tetapi yang penting dalam pembuatan file yang dapat dieksekusi adalah bahwa mesin yang berbeda memiliki target bahasa assembly yang berbeda, dan kode objek yang dihasilkan harus berbeda. Ini tidak sepenuhnya berbicara masalah "OS" melainkan masalah perangkat keras, tetapi tidak berarti bahwa Anda akan membutuhkan build yang berbeda untuk platform perangkat keras yang berbeda.

Gort the Robot
sumber
2
Mungkin bermanfaat untuk dicatat bahwa format yang dapat dieksekusi yang lebih sederhana dapat dimuat menggunakan hanya sejumlah kecil RAM (jika ada) di luar yang diperlukan untuk menyimpan kode yang dimuat, sementara format yang lebih kompleks mungkin memerlukan jejak kaki RAM yang jauh lebih besar selama, dan dalam beberapa kasus bahkan setelah itu, memuat. MS-DOS akan memuat file COM hingga 63.75K hanya dengan membaca byte berurutan ke RAM mulai dari offset 0x100 segmen sewenang-wenang, memuat CX dengan alamat akhir, dan melompat ke sana. Kompilasi single-pass dapat dilakukan tanpa back-patching (berguna dengan disket) oleh ...
supercat
1
... memiliki kompiler yang menyertakan setiap titik patch dengan setiap rutin, yang masing-masing akan menyertakan alamat dari daftar sebelumnya, dan menempatkan alamat daftar terakhir di akhir kode. OS hanya akan memuat kode sebagai byte mentah, tetapi rutin kecil dalam kode dapat menerapkan semua tambalan alamat yang diperlukan sebelum menjalankan bagian utama dari kode.
supercat
9

Dari jawaban saya yang lain:

Pertimbangkan mesin DOS awal, dan apa kontribusi nyata Microsoft terhadap dunia:

Autocad harus menulis driver untuk setiap printer yang dapat mereka cetak. Begitu juga lotus 1-2-3. Bahkan, jika Anda ingin perangkat lunak Anda dicetak, Anda harus menulis driver sendiri. Jika ada 10 printer, dan 10 program, maka 100 bagian berbeda dari kode yang sama harus ditulis secara terpisah dan independen.

Apa yang Windows 3.1 coba capai (bersama dengan GEM, dan begitu banyak lapisan abstraksi lainnya) adalah membuatnya sehingga pembuat printer menulis satu driver untuk printer mereka, dan programmer menulis satu driver untuk kelas printer windows.

Sekarang dengan 10 program dan 10 printer, hanya 20 lembar kode yang harus ditulis, dan karena sisi kode microsoft sama untuk semua orang, maka contoh dari MS berarti Anda hanya memiliki sedikit pekerjaan untuk dilakukan.

Sekarang sebuah program tidak terbatas hanya pada 10 printer yang mereka pilih untuk didukung, tetapi semua printer yang pembuatnya menyediakan driver di windows.

Jadi OS menyediakan layanan untuk aplikasi sehingga aplikasi tidak harus melakukan pekerjaan yang berlebihan.

Contoh program C Anda menggunakan printf, yang mengirimkan karakter ke stdout - sumber daya khusus OS yang akan menampilkan karakter pada antarmuka pengguna. Program tidak perlu tahu di mana antarmuka pengguna berada - itu bisa di DOS, bisa di jendela grafis, itu bisa disalurkan ke program lain dan digunakan sebagai input ke proses lain.

Karena OS menyediakan sumber daya ini, programmer dapat mencapai lebih banyak dengan sedikit kerja.

Namun, bahkan memulai suatu program pun rumit. OS mengharapkan file yang dapat dieksekusi untuk memiliki informasi tertentu di awal yang memberitahu OS bagaimana itu harus dimulai, dan dalam beberapa kasus (lingkungan yang lebih maju seperti android atau iOS) sumber daya apa yang akan diperlukan yang memerlukan persetujuan karena mereka menyentuh sumber daya di luar "kotak pasir" - langkah keamanan untuk membantu melindungi pengguna dan aplikasi lain dari program yang tidak pantas.

Jadi, bahkan jika kode mesin yang dapat dieksekusi adalah sama, dan tidak ada sumber daya OS yang diperlukan, program yang dikompilasi untuk Windows tidak akan berjalan pada sistem operasi OS X tanpa emulasi tambahan atau lapisan terjemahan, bahkan pada perangkat keras yang sama persis.

Sistem operasi gaya DOS awal seringkali dapat berbagi program, karena mereka menerapkan API yang sama dalam perangkat keras (BIOS) dan OS yang terhubung ke perangkat keras untuk menyediakan layanan. Jadi jika Anda menulis dan menyusun program COM - yang hanya merupakan gambar memori dari serangkaian instruksi prosesor - Anda dapat menjalankannya pada CP / M, MS-DOS, dan beberapa sistem operasi lainnya. Bahkan Anda masih dapat menjalankan program COM pada mesin windows modern. Sistem operasi lain tidak menggunakan kait API BIOS yang sama, sehingga program COM tidak akan berjalan di atasnya tanpa, sekali lagi, lapisan emulasi atau terjemahan. Program EXE mengikuti struktur yang mencakup lebih dari sekadar instruksi prosesor, dan seiring dengan masalah API itu tidak akan berjalan pada mesin yang tidak mengerti cara memuatnya ke dalam memori dan menjalankannya.

Adam Davis
sumber
7

Sebenarnya, jawaban sebenarnya adalah bahwa jika setiap OS memahami tata letak file biner yang dapat dieksekusi yang sama, dan Anda hanya membatasi diri pada fungsi standar (seperti di pustaka standar C) yang disediakan oleh OS (yang disediakan oleh OS), maka perangkat lunak Anda akan , pada kenyataannya, berjalan di OS apa pun.

Tentu saja, kenyataannya bukan itu masalahnya. Sebuah EXEfile tidak memiliki format yang sama sebagai ELFberkas, meskipun keduanya mengandung kode biner untuk CPU yang sama. * Jadi setiap sistem operasi akan perlu untuk dapat menafsirkan semua format file, dan mereka hanya tidak melakukan hal ini di mulai, dan tidak ada alasan bagi mereka untuk mulai melakukannya nanti (hampir pasti karena alasan komersial daripada alasan teknis).

Lebih jauh lagi, program Anda mungkin perlu melakukan hal-hal yang C library tidak menentukan bagaimana melakukannya (bahkan untuk hal-hal sederhana seperti daftar isi direktori), dan dalam kasus tersebut setiap OS menyediakan fungsinya sendiri untuk mencapai Anda tugas, tentu saja berarti tidak akan ada penyebut umum terendah untuk Anda gunakan (kecuali jika Anda membuat penyebut sendiri).

Jadi secara prinsip, sangat mungkin. Bahkan, WINE menjalankan executable Windows langsung di Linux.
Tapi ini pekerjaan yang berat dan (biasanya) tidak bisa dibenarkan secara komersial.

* Catatan: Ada lebih banyak file yang dapat dieksekusi daripada hanya kode biner. Ada satu ton informasi yang memberi tahu sistem operasi tentang apa yang tergantung pada pustaka file, berapa banyak memori yang dibutuhkan, fungsi apa yang diekspor ke pustaka lain yang mungkin bergantung padanya, di mana sistem operasi mungkin menemukan informasi debug yang relevan, bagaimana cara " cari kembali "file dalam memori jika perlu, bagaimana membuat penanganan perkecualian berfungsi dengan benar, dll. dll. lagi, mungkin ada satu format untuk ini yang disetujui semua orang, tetapi tidak ada.

Mehrdad
sumber
Fakta menyenangkan: ada format biner posiz terstandarisasi, yang dapat dijalankan di seluruh OS. Hanya saja tidak umum digunakan.
Marcin
@ Marsin: Sepertinya Anda tidak menganggap Windows sebagai OS. (Atau maksud Anda Windows dapat menjalankan binari POSIX ?!) Untuk keperluan jawaban saya, POSIX bukanlah jenis standar yang saya maksud. X dalam POSIX adalah singkatan dari Unix. Itu tidak pernah dimaksudkan untuk digunakan oleh misalnya Windows, meskipun Windows kebetulan memiliki subsistem POSIX.
Mehrdad
1. Sesuatu dapat berjalan di beberapa OS tanpa berjalan di semua OS; 2. Windows sejak NT telah dapat menjalankan binari posix.
Marcin
1
@ Marsin: (1) Seperti yang saya katakan, X di POSIX adalah singkatan dari UNIX . Ini bukan standar yang dimaksudkan untuk diikuti oleh OS lain, itu hanya upaya untuk mencapai penyebut umum antara berbagai Unix, yang hebat tapi tidak terlalu luar biasa. Fakta bahwa ada beberapa rasa Unix OS di luar sana benar-benar tidak relevan ke titik saya sudah berusaha untuk membuat mengenai kompatibilitas di lain sistem operasi dari Unix. (2) Bisakah Anda memberikan referensi untuk # 2?
Mehrdad
1
@Mehrdad: Marcin benar; Windows SUA (Subsistem untuk Aplikasi Unix) kompatibel dengan POSIX
MSalters
5

Diagram memiliki lapisan "aplikasi" (kebanyakan) terpisah dari lapisan "sistem operasi" oleh "perpustakaan", dan itu menyiratkan bahwa "aplikasi" dan "OS" tidak perlu saling mengenal satu sama lain. Itu adalah penyederhanaan dalam diagram, tetapi itu tidak sepenuhnya benar.

Masalahnya adalah bahwa "perpustakaan" sebenarnya memiliki tiga bagian untuk itu: implementasi, antarmuka ke aplikasi, dan antarmuka ke OS. Pada prinsipnya, dua yang pertama dapat dibuat "universal" sejauh menyangkut OS (itu tergantung di mana Anda mengirisnya), tetapi bagian ketiga - antarmuka ke OS - umumnya tidak bisa. Antarmuka ke OS tentu tergantung pada OS, API yang disediakannya, mekanisme pengemasan (mis. Format file yang digunakan oleh Windows DLL), dll.

Karena "perpustakaan" umumnya dibuat tersedia sebagai satu paket, itu berarti bahwa sekali program memilih "perpustakaan" untuk digunakan, itu berkomitmen untuk OS tertentu. Ini terjadi salah satu dari dua cara: a) programmer mengambil sepenuhnya di muka, dan kemudian pengikatan antara perpustakaan dan aplikasi dapat bersifat universal, tetapi perpustakaan itu sendiri terikat ke OS; atau b) programmer mengatur semuanya sehingga perpustakaan dipilih ketika Anda menjalankan program, tetapi kemudian mekanisme pengikatan itu sendiri, antara program dan perpustakaan, bergantung pada OS (misalnya, mekanisme DLL pada Windows). Masing-masing memiliki kelebihan dan kekurangan, tetapi Anda harus membuat pilihan terlebih dahulu.

Sekarang, ini tidak berarti bahwa itu tidak mungkin dilakukan, tetapi Anda harus sangat pintar. Untuk mengatasi masalah ini, Anda harus memilih rute mengambil perpustakaan saat run-time, dan Anda harus datang dengan mekanisme pengikatan universal yang tidak bergantung pada OS (sehingga Anda bertanggung jawab untuk memeliharanya, lebih banyak pekerjaan). Beberapa kali itu sepadan.

Anda tidak harus melakukannya, tetapi jika Anda akan berusaha untuk melakukan itu, ada peluang baik Anda tidak ingin terikat dengan prosesor tertentu, jadi Anda akan menulis Mesin Virtual dan Anda akan mengkompilasi program Anda ke format kode netral prosesor.

Sekarang kamu seharusnya sudah memperhatikan kemana aku pergi. Platform bahasa seperti Java melakukan hal itu. Java runtime (library) mendefinisikan pengikatan OS-netral antara program Java Anda dan perpustakaan (bagaimana Java runtime membuka dan menjalankan program Anda), dan menyediakan implementasi khusus untuk OS saat ini. .NET melakukan hal yang sama sampai batas tertentu, kecuali bahwa Microsoft tidak menyediakan "perpustakaan" (runtime) untuk apa pun kecuali Windows (tetapi yang lain lakukan - lihat Mono). Dan, sebenarnya, Flash juga melakukan hal yang sama, meskipun cakupannya lebih terbatas pada Browser.

Akhirnya, ada cara untuk melakukan hal yang sama tanpa mekanisme pengikatan khusus. Anda bisa menggunakan alat konvensional, tetapi tunda langkah mengikat ke perpustakaan sampai pengguna memilih OS. Itulah yang terjadi ketika Anda mendistribusikan kode sumber. Pengguna mengambil program Anda dan mengikatnya ke prosesor (kompilasi) dan OS (tautkan) ketika pengguna siap untuk menjalankannya.

Itu semua tergantung pada bagaimana Anda mengiris lapisan. Pada akhirnya, Anda selalu memiliki perangkat komputasi yang dibuat dengan perangkat keras khusus yang menjalankan kode mesin tertentu. Lapisan-lapisan itu ada sebagian besar sebagai kerangka kerja konseptual.

Euro Micelli
sumber
3

Perangkat lunak tidak selalu spesifik untuk OS. Baik Java dan sistem p-code sebelumnya (dan bahkan ScummVM) memungkinkan perangkat lunak yang portabel di seluruh Sistem Operasi. Infocom (pembuat Zork dan mesin-Z ), juga memiliki basis data relasional berdasarkan pada mesin virtual lain. Namun, pada tingkat tertentu, sesuatu harus menerjemahkan bahkan abstraksi-abstraksi itu menjadi instruksi aktual untuk dieksekusi di komputer.

Elliott Frisch
sumber
3
Java berjalan di mesin virtual, yang bukan cross-OS. Anda harus menggunakan biner JVM yang berbeda untuk setiap OS
Izkata
3
@Izkata Benar, tetapi Anda tidak mengkompilasi ulang perangkat lunak (hanya JVM). Juga, lihat kalimat terakhir saya. Tetapi saya akan menunjukkan bahwa Sun memang memiliki prosesor mikro yang dapat langsung mengeksekusi kode byte.
Elliott Frisch
3
Java adalah OS, meskipun biasanya tidak dianggap sebagai satu. Perangkat lunak Java khusus untuk OS Java, dan ada emulator Java OS untuk sebagian besar OS "nyata". Tetapi Anda dapat melakukan hal yang sama dengan host dan target OS - seperti menjalankan perangkat lunak Windows di Linux menggunakan WINE.
user253751
@ imibis saya akan lebih spesifik. Java Foundation Classes (JFC, perpustakaan standar Java) adalah sebuah kerangka kerja. Java sendiri adalah bahasa. JVM mirip dengan OS: ia memiliki "Mesin Virtual" dalam namanya, dan melakukan fungsi yang mirip dengan OS dari perspektif kode yang berjalan di dalamnya.
1

Kamu bilang

perangkat lunak yang diproduksi menggunakan bahasa pemrograman untuk sistem operasi tertentu hanya bekerja dengan mereka

Tetapi program yang Anda berikan sebagai contoh akan bekerja pada banyak sistem operasi, dan bahkan beberapa lingkungan bare-metal.

Yang penting di sini adalah perbedaan antara kode sumber dan biner yang dikompilasi. Bahasa pemrograman C secara khusus dirancang untuk menjadi OS independen dalam bentuk sumber. Ia melakukan ini dengan meninggalkan interpretasi hal-hal seperti "cetak ke konsol" hingga pelaksana. Tetapi C dapat memenuhi sesuatu yang spesifik OS (lihat jawaban lain untuk alasan). Misalnya, format PE atau ELF yang dapat dieksekusi.

Dan
sumber
6
Tampaknya cukup jelas bahwa OP bertanya tentang binari, bukan kode sumber.
Caleb
0

Orang lain telah membahas rincian teknis dengan baik, saya ingin menyebutkan alasan yang kurang teknis, sisi UX / UI:

Menulis Sekali, Rasakan Canggung Di Mana Saja

Setiap sistem operasi memiliki API antarmuka pengguna dan standar desain sendiri. Dimungkinkan untuk menulis satu antarmuka pengguna untuk suatu program dan menjalankannya pada banyak sistem operasi, namun hal itu semuanya menjamin bahwa program tersebut akan terasa tidak pada tempatnya di mana-mana. Membuat antarmuka pengguna yang baik membutuhkan penyesuaian detail untuk setiap platform yang didukung.

Banyak di antaranya adalah detail kecil, tetapi jika salah, Anda akan membuat pengguna Anda frustrasi:

  • Konfirmasi dialog memiliki tombol-tombol mereka dalam urutan berbeda di Windows dan OSX; dapatkan ini salah dan pengguna akan mengklik tombol yang salah dengan memori otot. Windows memiliki "Oke", "Batal" dalam urutan itu. OSX telah menukar order dan teks tombol do-it adalah deskripsi singkat dari tindakan yang harus dilakukan: "Batal", "Pindahkan ke Sampah".
  • Perilaku "kembali" berbeda untuk iOS dan Android. Aplikasi iOS menggambar tombol kembali sendiri sesuai kebutuhan, biasanya di kiri atas. Android memiliki tombol khusus di kiri bawah atau kanan bawah tergantung pada rotasi layar. Port cepat ke Android akan berperilaku salah jika tombol kembali OS diabaikan.
  • Pengguliran momentum berbeda antara iOS, OSX, dan Android. Sayangnya, jika Anda tidak menulis kode UI asli, Anda mungkin harus menulis perilaku pengguliran Anda sendiri.

Bahkan ketika secara teknis dimungkinkan untuk menulis satu basis kode UI yang berjalan di mana-mana, yang terbaik adalah membuat penyesuaian untuk setiap sistem operasi yang didukung.

Nick Pinney
sumber
-2

Perbedaan penting pada titik ini adalah memisahkan kompiler dari linker. Compiler kemungkinan besar menghasilkan output yang kurang lebih sama (perbedaannya sebagian besar disebabkan oleh berbagai #if WINDOWSs). Linker, di sisi lain, harus menangani semua hal platform spesifik - menghubungkan perpustakaan, membangun file yang dapat dieksekusi dll.

Dengan kata lain, kebanyakan kompiler peduli tentang arsitektur CPU, karena ia memproduksi kode runnable yang sebenarnya, dan harus menggunakan instruksi dan sumber daya dari CPU (perhatikan bahwa bytecode. IL atau JVM. NET akan dianggap sebagai set instruksi dari CPU virtual dalam tampilan ini). Inilah sebabnya mengapa Anda harus mengkompilasi kode secara terpisah untuk x86dan ARM, misalnya.

Linker, di sisi lain, harus mengambil semua data mentah dan instruksi ini, dan meletakkannya dalam format yang dapat dipahami oleh loader (hari ini, ini akan selalu menjadi OS), serta menghubungkan semua perpustakaan yang terhubung secara statis. (yang juga mencakup kode yang diperlukan untuk penautan dinamis, alokasi memori, dll.).

Dengan kata lain, Anda bisa mengkompilasi kode hanya sekali dan menjalankannya di Linux dan Windows - tetapi Anda harus menghubungkannya dua kali, menghasilkan dua executable yang berbeda. Sekarang, dalam praktiknya, Anda sering harus membuat kelonggaran dalam kode juga (di situlah arahan (pre-) kompilasi masuk), sehingga bahkan mengkompilasi tautan sekali dua kali tidak banyak digunakan. Belum lagi orang memperlakukan kompilasi dan menghubungkan sebagai satu langkah selama pembuatan (seperti Anda tidak lagi peduli dengan bagian-bagian dari kompiler itu sendiri).

Perangkat lunak era DOS sering lebih portabel biner, tetapi Anda harus memahami bahwa itu juga dikompilasi bukan terhadap DOS atau Unix, melainkan terhadap kontrak tertentu yang umum bagi kebanyakan PC bergaya IBM - melepaskan apa yang saat ini menjadi panggilan API untuk interupsi perangkat lunak. Ini tidak memerlukan penautan statis, karena Anda hanya perlu mengatur register yang diperlukan, panggil misalnya int 13huntuk fungsi grafis, dan CPU hanya melompat ke penunjuk memori yang dinyatakan dalam tabel interupsi. Tentu saja, sekali lagi, latihan itu jauh lebih sulit, karena untuk mendapatkan kinerja pedal-ke-the-metal, Anda harus menulis sendiri semua metode itu, tetapi itu pada dasarnya sama dengan menyiasati OS secara keseluruhan. Dan tentu saja, ada sesuatu yang selalu membutuhkan interaksi dengan OS API - penghentian program. Tapi tetap saja, jika Anda menggunakan format paling sederhana yang tersedia (misCOMpada DOS, yang tidak memiliki header, hanya instruksi) dan tidak ingin keluar, well - lucky you! Dan tentu saja, Anda bisa menangani terminasi yang tepat di runtime juga, sehingga Anda bisa memiliki kode untuk kedua terminasi Unix dan terminasi DOS di executable yang sama, dan mendeteksi pada saat runtime mana yang harus digunakan :)

Luaan
sumber
ini tampaknya hanya mengulangi poin yang dijelaskan dalam ini dan ini jawaban sebelumnya yang diposting kemarin
nyamuk