Compilerbau und Betriebssysteme
-
Hallo Freunde.
Ich interessiere mich seit kurzem für Compilerbau. Ich habe herausgefunden, dass ein Compiler grob gesagt den Text einer Sprache in Maschinensprache übersetzt, so dass die Maschine das Ergebnis ausführen kann.
Ich habe allerdings mal gehört, dass Betriebssysteme den direkten Zugriff auf Maschinen weg-abstrahieren.
Meine Frage wäre also: Wenn Betriebssysteme heutzutage den Zugriff auf die Maschine (im Normalfall) verhindern, und jemand einen Compiler (für bspw. C und die dazugehörige Standard-Bibo) bauen wollte - was ist dann die Zielsprache, wenn nicht Maschinensprache?
Wir können von normalen Desktop-Computern und Windows / Mac OS / Linux ausgehen. Kann da jemand was erhellendes zu sagen?
-
Da hast Du wahrscheinlich etwas falsch verstanden. Übersetzt wird immer noch hauptsächlich in Maschinencode (Ob jetzt durch einen Compiler, einen JIT-Compiler, einen Interpreter oder durch eine virtuelle Maschine).
https://en.wikipedia.org/wiki/Protection_ring
https://en.wikipedia.org/wiki/Protected_mode
-
@KlausDieter Moderne CPU können den Zugriff auf bestimmte Bereiche der Hardware unterbinden.
Dies wird vom Betriebssystem gesteuert, etwa indem Nutzerprogramme wenig Erlaubnis bekommen, Das Betriebssystem selber volle Kontrolle hat.
-
@KlausDieter sagte in Compilerbau und Betriebssysteme:
Ich habe allerdings mal gehört, dass Betriebssysteme den direkten Zugriff auf Maschinen weg-abstrahieren.
Meine Frage wäre also: Wenn Betriebssysteme heutzutage den Zugriff auf die Maschine (im Normalfall) verhindern, und jemand einen Compiler (für bspw. C und die dazugehörige Standard-Bibo) bauen wollte - was ist dann die Zielsprache, wenn nicht Maschinensprache?Also... jain.
"Zugriff auf die Maschine" ist halt ein sehr schwammiger Begriff. Aber dir geht es ja um die Maschinensprache. Und da ist es relativ einfach: der Code den dich moderne Betriebssysteme als normale Anwendung ausführen lassen ist schon immer noch in der selben Maschinensprache verfasst wie z.B. das Betriebssystem selbst verwendet. Da wird also nichts in dem Sinn "abstrahiert" wie es z.B. Java oder .NET machen. Daher brauchst du auch für Windows x86 ein anderes Programmfile wie für Windows auf ARM. Das selbe gilt bei Linux und so ziemlich jedem anderen Betriebssystem. Zumindest so lange es sich um "native" Anwendungen handelt.
Was das Betriebssystem aber u.A. macht ist den Prozessor in einem Modus zu schalten in dem er sich einfach weigert bestimmte Dinge zu tun. Also wenn dein Programm z.B. versucht Interrupts zu deaktivieren oder den Prozessor komplett anzuhalten, dann sagt der Prozessor "OK, schön dass du das willst, aber das darfst du nicht".
Davon abgesehen gibt es dann noch weitere Abstraktions- bzw. Schutzmechanismen. Ein solcher Mechanismus ist z.B. virtueller Speicher. D.h. dein Progamm kann nicht auf den ganzen Speicher des Computers zugreifen sondern nur auf einen abgeschotteten Bereich der halt für dein Programm bereitgestellt wird. Das Programm muss sich darum aber nur insoweit kümmern dass es über spezielle Funktionen des Betriebssystems den Speicher anfordern muss bevor es ihn verwenden kann. Das Betriebssystems sagt dann OK, hier hast du die gewünschte Menge Speicher, du kannst ab Adresse X darauf zugreifen. Der Mechanismus wie das Programm auf den Speicher zugreift ändert sich aber nicht - der Code in Maschinensprache bleibt der selbe. Der einzige Unterschied ist dass man nicht mehr fixe Adressen verwenden kann. (Wobei diese Einschränkung nichtmal für alle Systeme gilt. Es gibt Systeme wo das Programm dem Betriebssystem nur mitteilen muss was die höchste Speicheradresse ist die es zu verwenden gedenkt und dann alles von Null bis zu dieser Adresse selbst verwalten kann.)
Weiters ist direkter Zugriff auf Register der Hardware (HDD Controller, Grafikkarte, Soundkarte) nicht möglich. Wenn ein Programm versucht so einen Befehl zu verwenden, dann weigert sich der Prozessor einfach ihn auszuführen. Usw.Die Art und Weise wie die ganzen Befehle kodiert sind bleibt aber gleich. Beispiel: 0x31 0xC0 ist x86 Maschinensprache für
xor eax, eax
- ein sehr oft verwendeter Befehl der effektiv daseax
Register des Prozessors auf 0 setzt. Die Bytefolge funktioniert quasi auf allen x86 Systemen unabhängig vom Betriebssystem - angefangen von DOS über Windows 95 bis zu Windows 10, Linux, FreeBSD etc. Der Befehl ist "harmlos" und daher auch überall erlaubt.
Wenn du dagegen versuchst die Bytefolge 0xFA auszuführen die fürcli
steht und die Interrupt-Behandlung der CPU deaktiviert, dann wird das auf DOS funktionieren, aber auf Windows, Linux etc. nicht - weil die CPU dort in einem Modus läuft wo sie diesen Befehl einfach nicht akzeptiert.
-
@DirkB sagte in Compilerbau und Betriebssysteme:
@KlausDieter Moderne CPU können den Zugriff auf bestimmte Bereiche der Hardware unterbinden.
Dies wird vom Betriebssystem gesteuert, etwa indem Nutzerprogramme wenig Erlaubnis bekommen, Das Betriebssystem selber volle Kontrolle hat.Ist bei mir der gleiche Fall. Was für eine CPU gilt denn als modern? also ich habe jetzt ein Intel i3.
Liebe Grüße
-
@Nerdy22 sagte in Compilerbau und Betriebssysteme:
Was für eine CPU gilt denn als modern?
80286 ff
Edit:
In Bezug auf den Schutz zwischen Betriebssystem und Userspace
Es gab vorher schon welche, aber der 80286 wird der Bekanntere sein
-
@hustbaer sagte in Compilerbau und Betriebssysteme:
Die Bytefolge funktioniert quasi auf allen x86 Systemen unabhängig vom Betriebssystem - angefangen von DOS über Windows 95 bis zu Windows 10, Linux, FreeBSD etc. Der Befehl ist "harmlos" und daher auch überall erlaubt.
Ergänzend dazu:
Bei x86 gibt es bedeutend mehr Betriebsmodi als bei allen anderen CPUs, was einfach an der langen Lebensdauer der Plattform liegt. Man sieht sehr deutlich den Wandel von der 8Bit CPU (8008 und 8080) zur 16Bit CPU (8086) die fast identische Befehle wie der 8080 hat über den 80186 und 80286 (286 Protected Mode) hin zum 80386 mit dessen 386 Protected Mode. Dazu sieht man die Verwandtschaft mit dem 8080 noch den aktuellen CPUs an, weil noch immer die Register als 8Bit Register angesprochen werden können. Was sonst bei keiner anderen 32Bit oder 64Bit CPU möglich ist.Bei der 68000 Familien gab es nur den SuperVisor Mode und den User Mode, d.h. entweder läuft das OS oder eine Anwendung, wenn vorhanden wird der Speicher durch eine PMMU geschützt, was das OS macht und man als Anwender nichts damit zu tun hatte. Die Register sind immer 32Bit breit. 64Bit gab es nie, da Motorola vorher auf PowerPC wechselte.
@Nerdy22 sagte in Compilerbau und Betriebssysteme:
Ist bei mir der gleiche Fall. Was für eine CPU gilt denn als modern? also ich habe jetzt ein Intel i3.
Liebe GrüßeJedenfalls keine x86 CPU, weil die viel zu viele Altlasten aus 8Bit und 16Bit Zeiten mit sich herumschleppt. Das macht den Befehlssatz problematisch und die Optimierung in der CPU schwierig. Viele RISC CPUs sind als Load/Store-Architektur ausgelegt, d.h. Adressen liest man aus dem Speicher aus und speichert sie in ein Register und dann kann man das Register als Adresse für Speicheroperationen nutzen bzw. Operationen darauf ausführen z.B. Offset addieren o.ä. Bei den meisten CISC Architektur wurde eine Register/Memory-Architektur genutzt, und daher kann man direkt den Inhalt einer Speicherzelle als Quelle für Adressoperationen nutzen. Dann gibt es eine ganze Reihe von Optimierungen für Speicheroffsets die kleiner sind als 32Bit, so dass ein absoluter Wildwuchs an Adressierungsmodi existieren. Das macht aber die spekulative Ausführung von Code sehr schwierig, so dass Spectre und Co gerade bei Intel CPUs und teilweise AMD CPUs gar nicht so überraschend sind.
-
@DirkB
Naja, protected mode vom 286er war eher begrenzt. Richtig los ging das dann mit dem 386er.also ich habe jetzt ein Intel i3.
Du weisst schon dass "i3" ca. so viel heisst wie "3er BMW". Die aktuellen i3 (10xxxx) sind die 10. Generation.
Aber ja, ein i3 gilt auf jeden Fall in diesem Sinn als "moderne" CPU.
-
@hustbaer sagte in Compilerbau und Betriebssysteme:
Naja, protected mode vom 286er war eher begrenzt. Richtig los ging das dann mit dem 386er.
Hätte ich 80386 gelassen, hätte auch jemand was vom Protectet Mode im 80286 geschrieben.
-
@DirkB sagte in Compilerbau und Betriebssysteme:
Hätte ich 80386 gelassen, hätte auch jemand was vom Protectet Mode im 80286 geschrieben.
Vermutlich, ja