Maschinencode
Kurz: Maschinencode ist die Folge von Binärzahlen, die ein Prozessor direkt ausführen kann. Alle anderen Programmiersprachen müssen am Ende in diese Form gebracht oder von einem Programm ausgeführt werden, das sie ausführt.
Genauer: Ein Prozessor kennt nur seinen eigenen Befehlssatz, etwa x86-64 (Intel/AMD) oder ARM. Jeder Befehl ist eine Zahl: zum Beispiel „addiere diese zwei Register”. Maschinencode ist deshalb prozessorabhängig und für Menschen kaum lesbar.
Im Detail
Von der Hochsprache zum Maschinencode:
Quelltext (C, Rust, Go) ──Compiler──► Maschinencode ──► Prozessor
Quelltext (Java, C#) ──Compiler──► Bytecode ──JVM/CLR (Interpreter + JIT)──► Maschinencode
Quelltext (Python, JS) ──Interpreter──► führt Anweisungen aus (JS: JIT zu Maschinencode)
- Assembler: Eine lesbare Schreibweise für Maschinencode (
add rax, rbxstatt Zahlen). Er steht 1:1 für die Befehle. - Beispiel: Der x86-Befehl
B8 05 00 00 00lädt die Zahl 5 in ein Register (mov eax, 5). - Bytecode ist kein Maschinencode: Er ist ein Zwischenformat für eine virtuelle Maschine und läuft erst nach Übersetzung auf der CPU.
- Native Programme: Kompilierte C-, C++-, Rust- oder Go-Programme enthalten Maschinencode und starten ohne Laufzeitumgebung. Sie sind dafür an Prozessor und Betriebssystem gebunden.
- Portabilität: Ein x86-Programm läuft nicht auf ARM, außer es wird neu kompiliert oder emuliert (zum Beispiel Rosetta auf dem Mac).
- Ansehen:
objdump -d programm(Linux) oder ein Debugger zeigt den Maschinencode als Assembler. - Speicher: Maschinencode liegt im Arbeitsspeicher in einem als ausführbar markierten Bereich. Das Betriebssystem verbietet das Ausführen von Datenbereichen (NX-Bit), was viele Angriffe erschwert.
Siehe auch: Compiler, Bytecode, Interpreter