Różnica między programami skompilowanymi dla różnych systemów operacyjnych
8
Z punktu widzenia skompilowanego kodu jaka jest różnica między programem skompilowanym dla jednego systemu operacyjnego a drugim (na przykład Linux vs Windows). Czy program nie działa bezpośrednio na procesorze? A może dlatego, że program musi odwoływać się do bibliotek specyficznych dla systemu operacyjnego?
Zwykłe skompilowane programy działają „bezpośrednio” na CPU, ale program nie działa w próżni:
Wiele programów opiera się na zewnętrznych, dynamicznie ładowanych bibliotekach ( DLLslub .sobibliotekach). Sposób ich połączenia zależy od kompilatora / konsolidatora, a każdy system operacyjny ma inne standardy. Istnieją jednak również programy „połączone statycznie”, które udostępniają cały własny kod.
Nowoczesny system operacyjny nie zapewnia pełnej kontroli nad uruchomionym programem. Programy polegają na „wywołaniach systemowych” we / wy, dostępie do sprzętu i takich rzeczach, jak sygnały i przejście w stan uśpienia. Dostępne usługi i interfejs są definiowane przez system operacyjny. System operacyjny kontroluje również, z których części systemu (pamięć, rejestry, przerwania) program może korzystać.
Program GUI musi również pracować w środowisku graficznym użytkownika, aby narysować się na ekranie. Ale pewnie już o tym myślałeś.
Z tych powodów aplikacje niezależne od systemu operacyjnego muszą polegać na jakiejś „maszynie wirtualnej”, takiej jak ta zapewniana przez środowisko wykonawcze java. Co najważniejsze, VM zapewnia standardowy interfejs do zasobów systemu operacyjnego (we / wy, sygnałów itp.). Oczywiście java lub python również interpretują „kod bajtowy” zamiast zajmować się dziwactwami zestawu instrukcji Intela; ale to inna historia.
Ponadto różne systemy operacyjne mają różne standardy dotyczące układu stosu, praktyk wyrównywania pamięci itp., Więc nawet kod czysto numeryczny / obliczeniowy może wymagać różnych systemów operacyjnych.
Daniel R Hicks
Czy te różnice uniemożliwiłyby wykonanie statycznie skompilowanego kodu? Nie wiedziałem, że ...
Alexis
Prawdopodobnie jest to tylko problem teoretyczny, ponieważ jakaś inna niezgodność doprowadziłaby cię w pierwszej kolejności. Ale systemy operacyjne często mają oczekiwania co do sposobu wyrównania ramek stosu, gdzie przechowywane są rejestry itp. Mogą się one różnić w zależności od systemu operacyjnego dla tej samej architektury sprzętowej. Teoretycznie możesz uruchamiać „obcy” kod, który jest czysto obliczeniowy, ale nigdy nie byłbyś w stanie go uruchomić i nigdy nie byłby w stanie zakończyć go czysto.
Daniel R Hicks,
5
Różne systemy operacyjne mają również różne funkcje. Windows ma porty zakończenia we / wy, Linux nie. FreeBSD ma Kqueue, Linux nie. Linux ma futexy, Windows nie. Mają też różne sposoby robienia tego samego - jakie parametry przekazujesz, aby otworzyć plik? W jakiej kolejności się znajdują? Jak konkretnie wywołujesz funkcję „otwórz plik” systemu operacyjnego?
ok to ma sens, ale w ogóle, czy obciążenie programu do pamięci i uruchomić na cpu, czy też os „kontrolę” nad programem
AGZ
1
@agovizer: Oba. Nie wykluczają się wzajemnie. Zazwyczaj system operacyjny konfiguruje kontrolowane środowisko i ustawia, aby sprzęt przerwał program w określonym czasie, a następnie przekazał rdzeń programowi. Ale gdy tylko program napotka dowolną liczbę warunków (takich jak błąd strony, operacja We / Wy itp.), System operacyjny przejmuje ponownie.
Czy program nie działa bezpośrednio na procesorze?
NIE ! To zadanie dla systemu operacyjnego, aby zapobiec aplikacji z systemem „bezpośrednio” na CPU. Zazwyczaj na najniższym poziomie (tj. Tym, na którym zbudowany jest interfejs API systemu operacyjnego) aplikacja łączy się z jądrem systemu operacyjnego .
Czy to dlatego, że sam skompilowany program musi odwoływać się do bibliotek specyficznych dla systemu operacyjnego?
Tak . Wiele bibliotek systemu operacyjnego zostało napisanych w celu ułatwienia współpracy z samym systemem operacyjnym, ale jest ich tak wiele, że są przeznaczone dla różnych platform. Ukrywają one interfejs programisty niskiego poziomu przed deweloperem i zakładają, że skompilowana wersja dla tego systemu będzie dostępna w czasie wykonywania (patrz poniżej).
Chociaż biblioteki można pisać wieloplatformowo, po skompilowaniu nie można ich uruchamiać na różnych platformach. Nadal trzeba je ponownie skompilować dla konkretnego docelowego systemu operacyjnego, ponownie, aby wykorzystać określone podstawowe komponenty systemu operacyjnego (jądra).
Jaka jest różnica między skompilowanym programem dla jednego systemu operacyjnego a innym?
Wreszcie, same pliki wykonywalne często zawierają bardzo specyficzne binarne nagłówki ładujące i tak dalej (np. Format pliku wykonywalnego PE [.exe, .dll, itp ...] dla systemu Windows lub ELF dla systemu Linux [brak, .o, .so itp.]). Mogą one również zawierać kod do ładowania skompilowanych plików binarnych specyficznych dla systemu operacyjnego dla określonej biblioteki oprogramowania.
Wreszcie z perspektywy programisty: konwencja wywoływania . Skompilowany kod przekazuje zmienne do funkcji w określony sposób (tj. Przez rejestry lub na stosie) w bardzo określonej kolejności. Nawet wtedy należy również ustalić, kto jest odpowiedzialny za „wyczyszczenie” wywołań funkcji (osoba dzwoniąca czy odbiorca?). Chociaż istnieje kilka standardowych i powszechnie używanych konwencji wywoływania x86 , niektóre mogą nie być obsługiwane przez niektóre systemy operacyjne (jest to część ABI).
Różne systemy operacyjne mają również różne funkcje. Windows ma porty zakończenia we / wy, Linux nie. FreeBSD ma Kqueue, Linux nie. Linux ma futexy, Windows nie. Mają też różne sposoby robienia tego samego - jakie parametry przekazujesz, aby otworzyć plik? W jakiej kolejności się znajdują? Jak konkretnie wywołujesz funkcję „otwórz plik” systemu operacyjnego?
źródło
Zasadniczo programy nie są kompatybilne z powodu różnic w ich binarnym interfejsie aplikacji (ABI) .
NIE ! To zadanie dla systemu operacyjnego, aby zapobiec aplikacji z systemem „bezpośrednio” na CPU. Zazwyczaj na najniższym poziomie (tj. Tym, na którym zbudowany jest interfejs API systemu operacyjnego) aplikacja łączy się z jądrem systemu operacyjnego .
Tak . Wiele bibliotek systemu operacyjnego zostało napisanych w celu ułatwienia współpracy z samym systemem operacyjnym, ale jest ich tak wiele, że są przeznaczone dla różnych platform. Ukrywają one interfejs programisty niskiego poziomu przed deweloperem i zakładają, że skompilowana wersja dla tego systemu będzie dostępna w czasie wykonywania (patrz poniżej).
Chociaż biblioteki można pisać wieloplatformowo, po skompilowaniu nie można ich uruchamiać na różnych platformach. Nadal trzeba je ponownie skompilować dla konkretnego docelowego systemu operacyjnego, ponownie, aby wykorzystać określone podstawowe komponenty systemu operacyjnego (jądra).
Wreszcie, same pliki wykonywalne często zawierają bardzo specyficzne binarne nagłówki ładujące i tak dalej (np. Format pliku wykonywalnego PE [.exe, .dll, itp ...] dla systemu Windows lub ELF dla systemu Linux [brak, .o, .so itp.]). Mogą one również zawierać kod do ładowania skompilowanych plików binarnych specyficznych dla systemu operacyjnego dla określonej biblioteki oprogramowania.
Wreszcie z perspektywy programisty: konwencja wywoływania . Skompilowany kod przekazuje zmienne do funkcji w określony sposób (tj. Przez rejestry lub na stosie) w bardzo określonej kolejności. Nawet wtedy należy również ustalić, kto jest odpowiedzialny za „wyczyszczenie” wywołań funkcji (osoba dzwoniąca czy odbiorca?). Chociaż istnieje kilka standardowych i powszechnie używanych konwencji wywoływania x86 , niektóre mogą nie być obsługiwane przez niektóre systemy operacyjne (jest to część ABI).
źródło