Ich habe mich immer gefragt, wie ausführbare Binärdateien eigentlich funktionieren. Die Kompilierung wird immer wie folgt angegeben:
den Quellcode nehmen und ihn in Maschinensprache übersetzen
Doch was bedeutet das konkret? Nämlich:
- Kann ich eine Binärdatei von Computer A auf Computer B verschieben und erwarten, dass es funktioniert? (vorausgesetzt, ich verschiebe auch die entsprechenden Bibliotheken)
- Ist jede ausführbare Binärdatei für die Verwendung mit einem bestimmten Prozessor ausgelegt?
- Welche Art von Informationen enthält eine ausführbare Binärdatei?
- Wie kommt es, dass ausführbare Dateien unter Windows mit jeder beliebigen Windows-Version gestartet werden können? (Ob sie funktionieren, ist eine andere Geschichte.)
- Warum kann ich eine Linux-Programmdatei nicht unter Windows ausführen? Liegt das am Kernel (und nicht am Prozessor)?
Bedenken Sie, dass ich nur begrenzte Kenntnisse über Prozessoren und Compiler und keine über Assembler habe.
Antwort1
- Nicht unbedingt. Wenn es portabel ist und die Plattformen kompatibel sind, dann ja (z. B. können 64-Bit-Editionen von Windows 32-Bit- und 64-Bit-Windows-Programme ausführen, aber keine 16-Bit-Editionen mehr).
- Nicht unbedingt. Sie sind für einen bestimmten Befehlssatz gemacht. Da es sich dabei normalerweise um Erweiterungen handelt und Abwärtskompatibilität besteht, können Sie ältere Dateien auf neueren Prozessoren ausführen, aber nicht unbedingt umgekehrt. Beispielsweise läuft ein für Windows 95 kompiliertes Programm wahrscheinlich immer noch auf der heutigen Hardware, aber Sie können ein für die heutige Hardware kompiliertes Programm nicht auf einem alten Windows 95-Rechner ausführen. Wenn jedoch zwei Rechner völlig unterschiedliche Befehle ausführen, sind die ausführbaren Dateien nicht kompatibel (z. B. Intel vs. ARM).
- Dies ist plattformabhängig. Es gibt mehrere Formate mit unterschiedlichen Headern usw., aber grundsätzlich gibt es immer eine Art Header, der als Index fungiert und dem Betriebssystem mitteilt, wo bestimmte Dinge zu finden sind (z. B. der Haupteinstiegspunkt).
- Das können sie eigentlich nicht (siehe Nr. 2 oben).
- Zunächst einmal verwenden Windows und Linux unterschiedliche Formate für ihre ausführbaren Dateien. Aber selbst dann gibt es Unterschiede, zum Beispiel die gesamte Umgebung und die bereitgestellten Plattform-APIs/-Bibliotheken. Beispielsweise würde eine ausführbare Linux-Datei normalerweise versuchen, mit einem Fenstermanager wie X11 zu kommunizieren, während ein Windows-Programm versuchen würde, die Windows-API aufzurufen. Es gibt jedoch Möglichkeiten, solche Dinge zum Laufen zu bringen. Ältere Versionen von Windows (NT?) hatten tatsächlich POSIX-Erweiterungen, sodass Sie meines Wissens eine begrenzte Anzahl von Linux-Programmen ausführen konnten, obwohl ich das nie wirklich ausprobiert oder genauer untersucht habe. Auf der anderen Seite gibt es für Linux Tools wie Wine, die versuchen, die Windows-Umgebung zu emulieren und die API-Dateien, Pfadkonvertierungen usw. bereitzustellen. Es ist keine vollständige Emulation (wie bei der Verwendung einer virtuellen Maschine).
Antwort2
Nur unter sehr kontrollierten Umständen: Beide Computer müssen über einen kompatiblen Prozessor und ein kompatibles Betriebssystem verfügen.
Kein bestimmter Prozessor, sondern eine Reihe kompatibler Prozessoren. Beispielsweise funktioniert eine Datei, die für die Kompatibilität mit x86 kompiliert wurde und keine Erweiterungen enthält, auf jedem Intel- oder AMD-x86- oder x64-Prozessor, vorausgesetzt, das Betriebssystem ist kompatibel.
In erster Linie der Maschinencode aus dem Kompilierungsschritt. Darüber hinaus enthalten einige andere sogenannte „Abschnitte“ z. B. Ressourcen (haben Sie sich schon einmal gefragt, warum eine ausführbare Datei unter Windows ein eigenes Symbol hat, auch wenn sie nicht ausgeführt wird, sondern nur im Explorer angezeigt wird), die Beschreibung der Binärkompatibilität und mehr.
Dies ist ein Nebeneffekt von 1.: Wenn das Betriebssystem mit dem ausführbaren Format kompatibel ist, kann es ausgeführt werden. Moderne Windows-Versionen bieten eine Reihe von Kompatibilitäten: DOS, Win16, Win32, Win64 und dotnet sind die wichtigsten.
Das Betriebssystem stellt der ausführbaren Datei eine Umgebung zur Verfügung, die für die Ausführung unverzichtbar ist. Diese Umgebungen unterscheiden sich stark zwischen Linux und Windows. Das bedeutet, dass Sie ausführbare Dateien nicht direkt von einem Betriebssystem auf dem anderen ausführen können. Es gibt Projekte, die diese Lücke schließen sollen: Das WINE-Projekt zielt darauf ab, das Ausführen von Windows-ausführbaren Dateien unter Linux (und anderen Betriebssystemen) zu ermöglichen, während das Cygwin-Projekt das Ausführen von Linux-Software unter Windows ermöglichen soll. Cygwin zielt nicht auf Binärkompatibilität ab, sondern darauf, die Neukompilierung unveränderter Quellen zu ermöglichen.
Es ist wichtig zu verstehen, dass die ausführbare Datei (z. B. die .exe)nichtdas Ergebnis des Kompilierungsprozesses - es ist das Ergebnis derVerlinkungProzess, der die Ausgabe der Kompilierung mit den anderen Zutaten kombiniert, die zum Erstellen des unter 3. beschriebenen Vorgangs erforderlich sind.