Ausgabe 1 — Änderungen 1431 → 1432

Zeile 58: Zeile 58:
  
 
=== Unser Bootloader ===
 
=== Unser Bootloader ===
−
Zuerst einmal sucht das BIOS auf dem ersten Sektor von Diskette und Festplatte nach einer Bin�rdatei, die genau 512 Bytes (1 Sector) lang ist und am Ende das Wort 0x0AA55 enthält. Jetzt lädt das BIOS unseren Bootloader, wenn es ihn denn gefunden hat, an die Adresse 0x7C00. Damit alles so läuft, wie wir es uns gedacht haben, enth�lt die erste Zeile unseres Assemblercodes also den Code:
+
Zuerst einmal sucht das BIOS auf dem ersten Sektor von Diskette und Festplatte nach einer Binärdatei, die genau 512 Bytes (1 Sector) lang ist und am Ende das Wort 0x0AA55 enthält. Jetzt lädt das BIOS unseren Bootloader, wenn es ihn denn gefunden hat, an die Adresse 0x7C00. Damit alles so läuft, wie wir es uns gedacht haben, enthält die erste Zeile unseres Assemblercodes also den Code:
  
 
     ORG 0x7C00
 
     ORG 0x7C00
  
−
Diese Zeile regelt, dass all unsere Adressierungen richtig sind usw. Jetzt basteln wir einen Stack. Er sitzt an Adresse 0x9000. Den Stackpointer setzen wir auf null. Während wir das alles tun, sind übrigens keine Interrupts zugelassen. Nun schreiben wir die Information über das Bootlaufwerk aus DL in eine Variable, rufen die Funktion "load" auf und springen zum geladenen Programm, unserem Kernel rüber (das seht ihr im vollst�ndigen Code weiter unten).
+
Diese Zeile regelt, dass all unsere Adressierungen richtig sind usw. Jetzt basteln wir einen Stack. Er sitzt an Adresse 0x9000. Den Stackpointer setzen wir auf null. Während wir das alles tun, sind übrigens keine Interrupts zugelassen. Nun schreiben wir die Information über das Bootlaufwerk aus DL in eine Variable, rufen die Funktion "load" auf und springen zum geladenen Programm, unserem Kernel rüber (das seht ihr im vollständigen Code weiter unten).
 
<br><br>
 
<br><br>
 
Zum Schluss des Codes seht ihr noch folgende Zeilen:
 
Zum Schluss des Codes seht ihr noch folgende Zeilen:
Zeile 71: Zeile 71:
 
Sie sind für die Länge von 512 Bytes und das Wort 0x0AA55 am Ende zuständig.
 
Sie sind für die Länge von 512 Bytes und das Wort 0x0AA55 am Ende zuständig.
 
<br><br>
 
<br><br>
−
Hmmm... Das war jetzt noch nicht schwer - aber damit es funktioniert, brauchen wir noch diese Ladefunktion. Sie benutzt den BIOS-Interrupt 0x13, um auf das Laufwerk zuzugreifen und wenn das gelang, unser Binary vom 2. Sektor zu lesen. Dann gibt sie noch eine Meldung aus, damit wir im Fall eines Fehlers (bei einem sp�teren Kernel) wissen, ob das Laden wenigstens geklappt hat.
+
Hmmm... Das war jetzt noch nicht schwer - aber damit es funktioniert, brauchen wir noch diese Ladefunktion. Sie benutzt den BIOS-Interrupt 0x13, um auf das Laufwerk zuzugreifen und wenn das gelang, unser Binary vom 2. Sektor zu lesen. Dann gibt sie noch eine Meldung aus, damit wir im Fall eines Fehlers (bei einem sp&auml;teren Kernel) wissen, ob das Laden wenigstens geklappt hat.
 
<br>
 
<br>
 
Der Code am Stück
 
Der Code am Stück
Zeile 196: Zeile 196:
 
     getkey:
 
     getkey:
 
     mov ah, 0 ; Funktion 0
 
     mov ah, 0 ; Funktion 0
−
     int 016h  ; Ausf�hren
+
     int 016h  ; Ausf&uuml;hren
 
     ret
 
     ret
 
      
 
      
Zeile 220: Zeile 220:
 
     (den Anweisungen folgen, myOS.raw auf "a" schreiben)
 
     (den Anweisungen folgen, myOS.raw auf "a" schreiben)
  
−
Jetzt rebootet ihr ganz einfach euren Rechner mit unserer neuen bootf�higen Diskette im Laufwerk... TÄDÄÄÄÄÄÄH!!!
+
Jetzt rebootet ihr ganz einfach euren Rechner mit unserer neuen bootf&auml;higen Diskette im Laufwerk... T&Auml;D&Auml;&Auml;&Auml;&Auml;&Auml;&Auml;&Auml;H!!!
 
<br><br>
 
<br><br>
 
'''Anmerkung: ''' Wer sein OS mit [[Qemu]] testen will, sollte dafür sorgen, dass auch die Größes des Kernels durch 512 teilbar ist, da Qemu nur ganze Sektoren lädt.
 
'''Anmerkung: ''' Wer sein OS mit [[Qemu]] testen will, sollte dafür sorgen, dass auch die Größes des Kernels durch 512 teilbar ist, da Qemu nur ganze Sektoren lädt.
Zeile 236: Zeile 236:
  
 
==== Allgemeine Register ====
 
==== Allgemeine Register ====
−
Die allgemeinen Register sind 16 Bit breit, k�nnen aber jeweils in zwei 8 Bit breite Register aufgeteilt werden. Das niederwertige Register wird mit dem Buchstaben L, das höherwertige Register mit dem Buchstaben H gekennzeichnet. In Verbindung mit dem Buchstaben A, B, C oder D ergibt sich ein vollst�ndiger Registername. Zum Beispiel wird aus AX (16 Bit breit) das Register AL (8 Bit) und das Register AH (8 Bit). Änderungen an AL oder AH schlagen sich immer auch auf AX nieder.
+
Die allgemeinen Register sind 16 Bit breit, k&ouml;nnen aber jeweils in zwei 8 Bit breite Register aufgeteilt werden. Das niederwertige Register wird mit dem Buchstaben L, das höherwertige Register mit dem Buchstaben H gekennzeichnet. In Verbindung mit dem Buchstaben A, B, C oder D ergibt sich ein vollst&auml;ndiger Registername. Zum Beispiel wird aus AX (16 Bit breit) das Register AL (8 Bit) und das Register AH (8 Bit). Änderungen an AL oder AH schlagen sich immer auch auf AX nieder.
 
<br><br>
 
<br><br>
 
Und hier die einzelnen Register:
 
Und hier die einzelnen Register:
Zeile 270: Zeile 270:
 
     Segmentnummer * 16 Bytes
 
     Segmentnummer * 16 Bytes
  
−
Bis jetzt können wir nur auf Segmente oder besser Segmentgrenzen zugreifen. Um den Zugriff auf einzelne Bytes innerhalb der Segmente zu ermöglichen, wird ein zweites Register verwendet. Dieses enthält einen Zeiger auf ein bestimmtes Byte, letzlich auch nur eine Zahl. Um also das 4. Byte im 6. Segment ansprechen zu k�nnen, muss ins Segmentregister der Wert 6 und in das zweite Register der Wert 4 eingetragen werden. Eine vollständige Adresse errechnet sich folgenderma�en:
+
Bis jetzt können wir nur auf Segmente oder besser Segmentgrenzen zugreifen. Um den Zugriff auf einzelne Bytes innerhalb der Segmente zu ermöglichen, wird ein zweites Register verwendet. Dieses enthält einen Zeiger auf ein bestimmtes Byte, letzlich auch nur eine Zahl. Um also das 4. Byte im 6. Segment ansprechen zu k&ouml;nnen, muss ins Segmentregister der Wert 6 und in das zweite Register der Wert 4 eingetragen werden. Eine vollständige Adresse errechnet sich folgenderma&szlig;en:
  
 
     Segmentnummer * 16 + Offset (Abstand zum Segmentanfang)
 
     Segmentnummer * 16 + Offset (Abstand zum Segmentanfang)
Zeile 303: Zeile 303:
 
{| border="1"
 
{| border="1"
 
| CS || Codesegment || Enthält die Nummer des Segmentes, das den aktuellen Code enthält - siehe Informationen zum Register IP.
 
| CS || Codesegment || Enthält die Nummer des Segmentes, das den aktuellen Code enthält - siehe Informationen zum Register IP.
 +
|-
 
| DS || Datensegment || Enthält die Nummer des Segmentes, das die Daten enthält. Der Offset kann in verschiedenen Registern stehen oder als Konstante übergeben werden.
 
| DS || Datensegment || Enthält die Nummer des Segmentes, das die Daten enthält. Der Offset kann in verschiedenen Registern stehen oder als Konstante übergeben werden.
 +
|-
 
| ES || Extrasegment || Findet vor allem bei den Stringoperationen Verwendung, in diesen Fällen steht der Offset im Register DI.
 
| ES || Extrasegment || Findet vor allem bei den Stringoperationen Verwendung, in diesen Fällen steht der Offset im Register DI.
 +
|-
 
| SS || Stacksegment || Enthält die Nummer des Segmentes, das den Stack enthält. Offsets stehen in den Register BP oder SP. Die Bedeutung des Stack wird später geklärt.
 
| SS || Stacksegment || Enthält die Nummer des Segmentes, das den Stack enthält. Offsets stehen in den Register BP oder SP. Die Bedeutung des Stack wird später geklärt.
 +
|-
 
| FS || Erst ab dem 80386 || Dient vor allem als Zusatzsegmentregister, wird hauptsächlich im Protected Mode verwendet.
 
| FS || Erst ab dem 80386 || Dient vor allem als Zusatzsegmentregister, wird hauptsächlich im Protected Mode verwendet.
 +
|-
 
| GS || Erst ab dem 80386 || Dient vor allem als Zusatzsegmentregister, wird hauptsächlich im Protected Mode verwendet.
 
| GS || Erst ab dem 80386 || Dient vor allem als Zusatzsegmentregister, wird hauptsächlich im Protected Mode verwendet.
 
|}
 
|}
Zeile 367: Zeile 372:
 
Meistens sollen abhängig von diesem Zustand bestimmte Aktionen durchgeführt werden. Eine Verzweigung in einem Assemblerprogramm ist nur über Sprünge realisierbar. Im Befehlssatz des 8086 befinden sich die so genannten bedingten Sprungbefehle, die die Flags auswerten und entsprechend zu anderen Programmstellen verzweigen.
 
Meistens sollen abhängig von diesem Zustand bestimmte Aktionen durchgeführt werden. Eine Verzweigung in einem Assemblerprogramm ist nur über Sprünge realisierbar. Im Befehlssatz des 8086 befinden sich die so genannten bedingten Sprungbefehle, die die Flags auswerten und entsprechend zu anderen Programmstellen verzweigen.
 
<br><br>
 
<br><br>
−
Beim 8086 sieht es folgenderma�en aus ("_" bedeutet: reserviertes oder noch nicht belegtes Bit):
+
Beim 8086 sieht es folgenderma&szlig;en aus ("_" bedeutet: reserviertes oder noch nicht belegtes Bit):
  
 
{| border="1"
 
{| border="1"
Zeile 376: Zeile 381:
  
 
==== IP - Instruction Pointer ====
 
==== IP - Instruction Pointer ====
−
Dies ist eines der wichtigsten Register des Prozessors. Es enthält einen Zeiger auf die Adresse im Codesegment, an der der n�chste auszuführende Befehl steht (CS:IP).
+
Dies ist eines der wichtigsten Register des Prozessors. Es enthält einen Zeiger auf die Adresse im Codesegment, an der der n&auml;chste auszuführende Befehl steht (CS:IP).
 
<br><br>
 
<br><br>
 
Der Programmierer kann dieses Register nicht direkt beeinflussen. Eine Einflussnahme ist nur über die Sprungbefehle oder den Aufruf eines Unterprogramms oder einem Rücksprung aus einem solchen möglich.
 
Der Programmierer kann dieses Register nicht direkt beeinflussen. Eine Einflussnahme ist nur über die Sprungbefehle oder den Aufruf eines Unterprogramms oder einem Rücksprung aus einem solchen möglich.
  
−
=== Spätere Prozessorgenerationen ===
+
=== Sp&auml;tere Prozessorgenerationen ===
 
Die Entwicklung ist selbstverständlich nicht beim 8086 stehen geblieben. Intel brachte noch eine Reihe weiterer Prozessoren heraus, die natürlich um Befehle, Register und Fähigkeiten erweitert wurden, trotzdem aber Kompatibilität zum jeweiligen Vorgänger wahrten.
 
Die Entwicklung ist selbstverständlich nicht beim 8086 stehen geblieben. Intel brachte noch eine Reihe weiterer Prozessoren heraus, die natürlich um Befehle, Register und Fähigkeiten erweitert wurden, trotzdem aber Kompatibilität zum jeweiligen Vorgänger wahrten.
 
<br>
 
<br>
Zeile 409: Zeile 414:
  
 
==== 80386 DX/SX ====
 
==== 80386 DX/SX ====
−
Die allgemeinen Register, die Index- und Pointerregister, das Flagregister und IP wurden auf 32 Bit erweitert. Ansprechbar werden die vollen 32 Bit durch Voranstellen eines "E" vor den ursprünglichen Registernamen, also z.B. EAX, ESI, EBP. Die niederwertigen 16 Bit entsprechen dem urspr�nglichen 16-Bit-Register. Auf die oberen 16 Bit kann man nur über einen Umweg zugreifen. Ebenso wurden die meisten Befehle so erweitert, dass sie mit 32-Bit-Operanden arbeiten k�nnen.
+
Die allgemeinen Register, die Index- und Pointerregister, das Flagregister und IP wurden auf 32 Bit erweitert. Ansprechbar werden die vollen 32 Bit durch Voranstellen eines "E" vor den ursprünglichen Registernamen, also z.B. EAX, ESI, EBP. Die niederwertigen 16 Bit entsprechen dem urspr&auml;nglichen 16-Bit-Register. Auf die oberen 16 Bit kann man nur über einen Umweg zugreifen. Ebenso wurden die meisten Befehle so erweitert, dass sie mit 32-Bit-Operanden arbeiten k&ouml;nnen.
 
<br><br>
 
<br><br>
 
Die SX-Variante wurde gegenüber der DX-Variante in ihren Kontaktmöglichkeiten mit der Außenwelt eingeschränkt. Statt 32 Datenleitungen (DX) erhielt sie nur 24, d.h. auch hier waren mehr Zugriffe nötig, was aber für den Programmierer ohne Belang ist.
 
Die SX-Variante wurde gegenüber der DX-Variante in ihren Kontaktmöglichkeiten mit der Außenwelt eingeschränkt. Statt 32 Datenleitungen (DX) erhielt sie nur 24, d.h. auch hier waren mehr Zugriffe nötig, was aber für den Programmierer ohne Belang ist.
Zeile 422: Zeile 427:
  
 
==== 80486 DX/SX ====
 
==== 80486 DX/SX ====
−
Die Möglichkeit der parallelen Befehlsverarbeitung wurde verbessert indem die Befehlsdecodierungseinheit und die Ausführungseinheit zu 5 in einer Pipeline angeordneten Stufen erweitert wurden. Zus�tzlich wurde noch ein 8 KB First-Level-Cache auf dem Prozessor untergebracht der vor allem den Zugriff auf Speicheroperanden drastisch erhöhte wenn sie sich bereits im Cache befanden. Beim 486 DX gelang Intel endlich die Vereinigung des normalen Prozessors mit einem numerischen Coprozessor. Unterstützung für Second Level Cache und Multiprozessorsysteme wurde ebenfalls eingebaut.
+
Die Möglichkeit der parallelen Befehlsverarbeitung wurde verbessert indem die Befehlsdecodierungseinheit und die Ausführungseinheit zu 5 in einer Pipeline angeordneten Stufen erweitert wurden. Zus&auml;tzlich wurde noch ein 8 KB First-Level-Cache auf dem Prozessor untergebracht der vor allem den Zugriff auf Speicheroperanden drastisch erhöhte wenn sie sich bereits im Cache befanden. Beim 486 DX gelang Intel endlich die Vereinigung des normalen Prozessors mit einem numerischen Coprozessor. Unterstützung für Second Level Cache und Multiprozessorsysteme wurde ebenfalls eingebaut.
  
 
==== Pentium ====
 
==== Pentium ====
Zeile 431: Zeile 436:
 
Beim Pentium endlich legte Intel einen Befehl bei, der nicht nur einen herstellerspezifischen String zurückgab (GenuineIntel, AuthenticAMD bei AMD-Prozessoren), sondern auch Informationen über verschiedene Prozessorfähigkeiten zu liefern vermochte. Das sind natürlich Fähigkeiten, die sich viele Programmierer schon viel früher gewünscht hätten, die jetzt aber umso mehr genutzt werden.
 
Beim Pentium endlich legte Intel einen Befehl bei, der nicht nur einen herstellerspezifischen String zurückgab (GenuineIntel, AuthenticAMD bei AMD-Prozessoren), sondern auch Informationen über verschiedene Prozessorfähigkeiten zu liefern vermochte. Das sind natürlich Fähigkeiten, die sich viele Programmierer schon viel früher gewünscht hätten, die jetzt aber umso mehr genutzt werden.
 
<br><br>
 
<br><br>
−
Der Pentium enthielt eine zweite Ausführungseinheit was die Ausführung von theoretisch zwei Befehlen je Takt ermöglichte. Der First-Level-Cache wurde auf 16 KB erweitert (je 8 KB für Code und Daten). Beim Paging konnte die Größe einer Page auf 4 MB erh�ht werden. Sprungvorhersage konnte die Performance in Schleifenkonstrukten steigern. Neben neuen Befehlen erhielt der Pentium einen weiteren Betriebsmodus (SMM).
+
Der Pentium enthielt eine zweite Ausführungseinheit was die Ausführung von theoretisch zwei Befehlen je Takt ermöglichte. Der First-Level-Cache wurde auf 16 KB erweitert (je 8 KB für Code und Daten). Beim Paging konnte die Größe einer Page auf 4 MB erh&ouml;ht werden. Sprungvorhersage konnte die Performance in Schleifenkonstrukten steigern. Neben neuen Befehlen erhielt der Pentium einen weiteren Betriebsmodus (SMM).
 
<br><br>
 
<br><br>
 
Mit einer späteren Version des Pentium führte Intel die MMX-Technologie ein. Dabei kommt das SIMD-Modell (Single Instruction, Multiple Data) zur parallelen Berechnung von Werten in den MMX-Registern. MMX sollte vor allem der Leistungssteigerung im Multimediabereich (Bild/Film-und Tonbearbeitung) dienen. Tatsächlich handelt es sich bei den MMX-Registern nicht um neue Register. Stattdessen werden die Register der FPU verwendet. Deswegen ist bei der Arbeit mit der FPU zu beachten, dass nicht auch gleichzeitig MMX-Befehle abgearbeitet werden (und umgekehrt).
 
Mit einer späteren Version des Pentium führte Intel die MMX-Technologie ein. Dabei kommt das SIMD-Modell (Single Instruction, Multiple Data) zur parallelen Berechnung von Werten in den MMX-Registern. MMX sollte vor allem der Leistungssteigerung im Multimediabereich (Bild/Film-und Tonbearbeitung) dienen. Tatsächlich handelt es sich bei den MMX-Registern nicht um neue Register. Stattdessen werden die Register der FPU verwendet. Deswegen ist bei der Arbeit mit der FPU zu beachten, dass nicht auch gleichzeitig MMX-Befehle abgearbeitet werden (und umgekehrt).
Zeile 457: Zeile 462:
 
Der P4 enthält eine ganze Reihe von Neuerungen. Zum einen basiert er auf der Intel NetBurst Mikro-Architektur, zum anderen bietet er SSE2, die MMX und SSE um 144 neue Befehle erweitern (Berechnungen mit 128-Bit-Operanden, Cache- und Speichermanagement) und Multimediaanwendungen weiter beschleunigen.
 
Der P4 enthält eine ganze Reihe von Neuerungen. Zum einen basiert er auf der Intel NetBurst Mikro-Architektur, zum anderen bietet er SSE2, die MMX und SSE um 144 neue Befehle erweitern (Berechnungen mit 128-Bit-Operanden, Cache- und Speichermanagement) und Multimediaanwendungen weiter beschleunigen.
 
<br><br>
 
<br><br>
−
Des Weiteren arbeitet er mit dem neuen 400 MHz Intel NetBurst Bus und ist dabei immer noch kompatibel zu allen Anwendungen die f�r die 32-Bit-Intel Prozessoren geschrieben wurden.
+
Des Weiteren arbeitet er mit dem neuen 400 MHz Intel NetBurst Bus und ist dabei immer noch kompatibel zu allen Anwendungen die f&uuml;r die 32-Bit-Intel Prozessoren geschrieben wurden.
 
<br><br>
 
<br><br>
  
Zeile 524: Zeile 529:
 
Ein wenig seltsam, aber gut durchdacht. Die meisten OSes basieren auf einer Shell und die GUI ist schmückendes Beiwerk. Bei MenuetOS ist es genau anders herum: die tolle GUI steht im Vordergrund, die Shell ist ein wenig mager geraten. Obwohl man eine richtige Shell vermisst, kann man sich sehr schnell in die GUI reinarbeiten.
 
Ein wenig seltsam, aber gut durchdacht. Die meisten OSes basieren auf einer Shell und die GUI ist schmückendes Beiwerk. Bei MenuetOS ist es genau anders herum: die tolle GUI steht im Vordergrund, die Shell ist ein wenig mager geraten. Obwohl man eine richtige Shell vermisst, kann man sich sehr schnell in die GUI reinarbeiten.
  
−
=== Funktionalität ===
+
=== Funktionalit&auml;t ===
 
Umfangreich. Hier ein Auszug aus der Features-Liste:
 
Umfangreich. Hier ein Auszug aus der Features-Liste:
  
Zeile 537: Zeile 542:
 
Vorbildlich: zu jedem Feature gibt es gleich das passende Beispielprogramm.
 
Vorbildlich: zu jedem Feature gibt es gleich das passende Beispielprogramm.
  
−
=== Stabilität / Kompatibilität ===
+
=== Stabilit&auml;t / Kompatibilität ===
 
Sehr gut. Kein einziges Kompatibilitätsproblem und während dem Test nur ein einziger Absturz (selbst dieser wahrscheinlich wegen unsachgemäßer Bedienung).
 
Sehr gut. Kein einziges Kompatibilitätsproblem und während dem Test nur ein einziger Absturz (selbst dieser wahrscheinlich wegen unsachgemäßer Bedienung).
  
Zeile 546: Zeile 551:
 
MenuetOS ist ein Betriebssystem, bei dem man auf mehr hoffen kann. Die Entwickler haben bereits jetzt ein sehr solides OS gemacht, und mit ein wenig Arbeit wird MenuetOS ein tolles Hobby-OS!
 
MenuetOS ist ein Betriebssystem, bei dem man auf mehr hoffen kann. Die Entwickler haben bereits jetzt ein sehr solides OS gemacht, und mit ein wenig Arbeit wird MenuetOS ein tolles Hobby-OS!
  
−
== Nächste Ausgabe ==
+
== N&auml;chste Ausgabe ==
  
 
Für die nächste Ausgabe sind folgende Themen geplant:
 
Für die nächste Ausgabe sind folgende Themen geplant: