Wieso kann man den selben Maschinencode nicht unter Mac, Linux und Windows ausführen?

T

Tersus

Gast
Ich habe drei Rechner, alle mit der gleichen CPU bzw. dem selben Modell. Ich schreibe nun ein Programm in Linux und kompiliere es. Ich erhalte eine Output-File, die mit Maschienen-Code gefüllt ist. Das Programm gibt mir "Hello World" auf der Konsole aus. Wieso kann ich diese Datei, so wie sie ist, nicht auch unter Mac und Windows ausführen? Kann mir jemand eine gute Referenz geben?

Grüße
 
Weil du andere Systemcalls hast. Jedes OS stellt eine API zur Verfügung, bspw. für die Ausgabe in der Konsole, für Tastatur und Mauseingaben, etc..

Immer dann, wenn du einen solchen Systemcall aufrufst wirst du auf anderen Maschinen evtl. Probleme mit dem Compilat bekommen, das ja für genau ein System bzw. für eine definierte Übermenge von Systemen ist.
 
Für solche Fälle gibt's verschiedene Lösungen:

1. Interpreter Sprachen wie z.B. Ruby, Python, PHP
2. Bytecode Sprachen wie z.B. Java oder C#
3. Frameworks, die Code für mehrere Umgebungen erzeugen wie z.B. Qt
 
Das was du nach dem Kompilieren hast, ist eben noch kein Maschinencode, der genau so auf der Hardware ausgeführt wird. Es handelt sich dabei um Code der auf einer bestimmten Plattform ausgeführt wird. Zwischen deinem Code und der eigentlichen Hardware ist noch eine Schicht des jeweiligen Betriebssystems.

Deine Annahme ist also schon falsch. Hättest du Code, der direkt auf der Hardware ausgeführt wird, könntest du dies natürlich unabhängig vom laufenden Betriebssystem tun. Der Charme des Betriebssystems ist aber, dass du dir eben keine Gedanken darüber machen musst, welche Hardware genau darunter liegt und du nicht alle Operationen selbst schreiben brauchst. Du kannst Bibliotheken verwenden, um dir das Leben leichter zu machen.
 
Meine Vorposter haben es ja schon angedeutet. In deinem Programm ist ja nur "schreibe >Hello World< drin". Der ganze Rest, wie die Konsole, Dateiverwaltung, Tastatur eingaben etc. wird vom Betriebssystem gestellt und verwaltet. Und das macht jedes OS natürlich etwas anderes.
Du könntest natürlich ein Programm schreiben, dass ganz ohne OS auskommt. Dann müsstest du aber deine eigene Grafikausgabe und dein eigenes Dateihandling etc. auch mit in dein Programm packen und auf die jeweilige Hardware zuschneiden.
 
Wenn du deinen Code in x86 oder x64-Assembler schreiben würdest, könntest du ihn vermutlich auf allen deinen Rechnern ausführen. Hier z.B. ein Hello World in x64 Assembler: http://0xax.blogspot.de/2014/08/say-hello-to-x64-assembly-part-1.html

Assembler Programmierung macht aber nicht wirklich Spaß wenn dein Programm einigermaßen komplex ist, deswegen gibt es die Hochsprachen wie C, C++, etc. die dann später beim Kompilieren übersetzt werden
 
Lhurgoyf schrieb:
Wenn du deinen Code in x86 oder x64-Assembler schreiben würdest, könntest du ihn vermutlich auf allen deinen Rechnern ausführen.
Nö, nur weil du Code in Assembler schreibst ist er nicht auf magische Weise OS unabhängig.
Selbst bei dem simplen 'Hello World' das du verlinkt hast sind im Code 2 syscalls (Aufrufe von OS-Funktionen), es gilt also auch für Assembler Code das was sdwaroc schon gesagt hat.
 
The_1st_Knight schrieb:
Das was du nach dem Kompilieren hast, ist eben noch kein Maschinencode, der genau so auf der Hardware ausgeführt wird. Es handelt sich dabei um Code der auf einer bestimmten Plattform ausgeführt wird. Zwischen deinem Code und der eigentlichen Hardware ist noch eine Schicht des jeweiligen Betriebssystems.
Doch, das was nach dem Kompilieren raus kommt IST Maschinencode (zumindest bei üblichen Compileraufrufen für native Sprachen wie c). Das Betriebssystem kommt nur ins Spiel wenn du dessen Funktionen aufrufst oder wenn Interupts verarbeitet werden müssen.
 
Miuwa schrieb:
Doch, das was nach dem Kompilieren raus kommt IST Maschinencode (zumindest bei üblichen Compileraufrufen für native Sprachen wie c). Das Betriebssystem kommt nur ins Spiel wenn du dessen Funktionen aufrufst oder wenn Interupts verarbeitet werden müssen.
Naja. Strenggenommen kommt das Betriebssystem schon beim Aufruf ins Spiel. Irgendwer muss ja die Datei in den RAM laden und dann an den Ausführungsstart springen. Ohne betriebssystem gibts aber weder das Konzept der Datei, noch das laden. Noch kann irgendwer den Inhalt in den RAM schreiben.

Und die Datei selbst ist auch kein reiner Maschenencode-Block, weil üblicherweise hat das ein Dateiformat wie EXE bei Windows oder Elf bei Linux. Da stehen dann auch bestimmte sachen drin, die für die Initialisierung wichtig sind. Da müssen Speicheradressen berechnet werden usw.
Wobei zugegebenermaßen diese "EXE-Dateien" nicht durch den Compiler selbst erzeugt werden, sondern durch den Linker. Was aber nicht unbedingt so getrennt sein muss bzw. nimmt man die Trennung heutzutage auch nicht mehr unbedingt so wahr.

Ansonsten hast Du natürlich generell recht. Alle Abschnitte, wo nur lediglich Register gefüllt werden oder Rechenoperation durchgeführt werden etc. ... sprich alles, wofür kein extra irgendwo liegender Code notwendig ist, läuft natürlich prinzipiell überall, solange es zur Rechnerarchitektur/Instraction-Set/etc. passt.
 
@andy_m4: Ich gebs zu, das war etwas vereinfacht Ausgedrück Den Start einer Anwendung hätte ich jetzt aber einfach mal zu den Betriebssystemfunktionsaufrufen gezählt.
 
Zurück
Oben