Ich lese gerade ein Tutorial über die OS entwicklung. http://www.henkessoft.de/OS_Dev/OS_Dev1.htm#mozTocId786364 Da wird in der ersten Zeile des Kernels (zu Anfang nur ein Hello World Kernel) in das Register AX der Wert 0x07C0 geladen. Diesen Schritt verstehe ich noch. Dann aber wird der Wert von AX in DS und ES geladen. Als Kommentar steht "set up segments". Wofür muss ich diesen Wert in DS und ES laden? Wozu sind diese Register da? Ersten 3 Zeilen Code aus dem Tutorial: mov ax, 0x07C0 ; set up segments mov ds, ax mov es, ax
Das sind Segmentregister. "In real mode the registers CS, DS, SS, and ES point to the currently used program code segment (CS), the current data segment (DS), the current stack segment (SS), and one extra segment determined by the programmer (ES)." http://en.wikipedia.org/wiki/X86_memory_segmentation
ok danke, aber was nützt es, wenn ich das Datasegment und das Extrasegment an die gleiche Adresse lege?
Zwingt dich niemand dazu. Hängt davon ab, was du machen willst.
Wenn du auf eine Speicheradresse zugreifst, dann wird die physikalische Adresse aus Segment und Adresse berechnet. Das Segment wird um 4 Bits nach links geshiftet und die Adresse hinzuaddiert. Du kannst es dir auch so vorstellen, dass der Arbeitsspeicher aus Segmenten besteht, wovon jedes 16 Byte groß ist. Segment 0x0000 - 16 Byte Segment 0x0001 - 16 Byte usw. Jetzt können sich die Bereiche aber überlappen, da du ja auch 16 Bit Adressen hast. Segment 0x0000 mit Adresse 0x0010 zeigt auf den selben Speicherbereich wie Segment 0x0001 mit Adresse 0x0000. Und etwas Hintergrundwissen: Das BIOS lädt den Bootsector oder den MBR an die Adresse 0x7C00. Wenn in deinem Assemblercode des BS oder MBR Variablen sind, z.B. das 5. Byte, dann müsstest du immer die Adresse 0x7C00 mit verrechnen - 5. Byte wird zu Adresse 0x7C05. Setzt du dagegen das Segmentregister auf 0x07C0, dann kannst du das 5. Byte auch mit Adresse 5 adressieren. DS ist das Segmentregister für Datenzugriffe (Read/Write), CS für Codezugriffe(Wird also mit dem IP verrechnet) und ES für Extrzugriffe (Benötigt bei z.B. CMPS).
Und gibt es irgendwo eine Liste mit den Regsitern, die nach dem Booten gefüllt werden müssen? Also so etwas ähnliches wie der Start von jedem Kernel.
Noch eine Frage: Im nächsten Schritt soll eine Trennung zwischen Bootloader und Kernel stattfinden. Dazu muss ja die Startadresse des Kernels verändert werden. Im ersten Teil des Tutorials war sie ja 0x07C0. Jedoch soll sie jetzt auf 0x7C00 gesetzt werden. Mach man das nur, um den Bootloader mehr Platz zu geben?
Gegenfrage: Für einen Kurzen Moment muss Bootloader und Kernel gleichzeitig im RAM stehen. Geht das, wenn beide auf derselben Adresse liegen?
Bei Adressierung z.B. DS:SI ist 0000:7C00 die gleiche Adresse wie 07C0:0000 wenn ich mich nicht irre. Meine DOS-Assembler-Programmierung ist leider schon eine Weile her.
Moment, ich blick immer noch nicht durch. Am Anfang war Bootloader und Kernel in der selben Datei. Da war der Anfang bei 0c07C0. Jetzt sollte der Anfang des Bootloaders aber bei 0x7C00 und der des Kernel bei 0x1000 sein. Das macht irgendwie keinen Sinn, oder?
@Magic_smoke aber es wird immer nur das Register DS beschrieben, nie das Register SI.
oh... Im Bootloader Sourcecode wird nicht so gearbeitet: mov AX, 0x07C0 mov DS, AX sondern so: org 0x7C00 macht das einen Unterschied?
Ja, das macht einen Unterschied. DS=0x07C0 => Adresse 0x0000 org 0x7C00 weist den Assembler an, sich den Dateianfang an Adresse 0x7C00 zu denken. Daraus würde dann DS=0x0000 und Adresse=0x7C00 ergeben.
Ah ok. Dann noch eine letzte Frage ;) Was macht dieser Befehl hier (ich weiß nicht mal den Ansatz): mov [bootdrive], dl call load_kernel load_kernel: mov dl,[bootdrive] xor ax, ax int 0x13 jc load_kernel
xor AX,AX Setzt AX auf 0, nur "schneller und kürzer" als ein MOV :) INT 13 Ruft INT 13 auf, das sind BIOS-Funktionen :) INT 13 mit AX==0: "Reset Drive Status". http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D00h:_Reset_Disk_Drive jc load_kernel: Wenn Fehler: Gleich nochmal...
Für den Prozessor nicht. Bei .EXE-Dateien ist im Header auch eine Einsprungadresse in das Programm angegeben. DOS lädt die Datei also ins RAM und springt dann an diese Adresse. .COM-Dateien haben das nicht, die werden ins RAM geladen und immer bei CS:0100 angesprungen. CS ist immer variabel, da das Programm keinen Einfluß darauf hat, an welche Stelle im RAM es geladen wird. Die x86-Prozessoren können nur bestimmte (nicht-Segment) Register zur Adressierung nutzen. Beispielsweise DS:SI, ES:DI, CS:IP, SS:SP. Was nicht geht ist z.B. DS:AX, CS:CX oder AX:BX.
Ok danke! Soweit verstehe ich es. Nur was macht das mov dl, [bootdrive] ?
>mov [bootdrive], dl hier schreibst du den Inhalt von Register dl an die Speicheradresse bootdrive. Die [] ist die Intel Syntax, dass das, was dazwischen steht, als Adresse aufgefasst werden soll. >call load_kernel Hier machst du einen call. Der schreibt die Rücksprungadresse auf den Stack und springt an die Adresse load_kernel >load_kernel: Das hier weißt den Assembler an, load_kernel mit der Adresse zu verknüpfen, die an der Stelle in der Datei vorliegt. Hier ist jetzt ein großer Unterschied ob CS=0x07C0 oder org 0x7C00 benutzt wurde. >mov dl,[bootdrive] Hier schreibst du den Inhalt des Speichers an Adresse bootdrive zurück ins Register dl. >xor ax, ax Hiermit setzt du Register ax auf Null. (xor mit sich selbst setzt alle Bits auf 0 und braucht bei einem x86er weniger Bytes als mov ax, 0x0000) >int 0x13 Interrupt 0x13 aufrufen, davor noch die Rücksprungadresse auf den Stack legen. >jc load_kernel Wenn das Carry Bit gesetzt ist, dann springe zu Adresse load_kernel
Samuel J. schrieb: > mov dl, [bootdrive] dasselbe wie jeder andere MOV Befehl, einen Wert Kopieren, nicht MOVen ... In diesem Fall: RAM -> Register...
Es lädt DL mit dem Byte an Adresse DS:[bootdrive] wobei bootdrive ein irgendwo definierter offset ist.
Nicht ganz sicher. Der Bios setzt Dir im DL Register das Bootlaufwerk zB 0x80 die erste Festplatte. mov [xyz],dl speichert Dir das Laufwerk in die Adresse xyz alle Biosfunktionen 0x13 wollen das anzusprechende Laufwerk in dl deshalb mov dl,[xyz] ; dl enthaelt das Bootlaufwerk mov ah,42h ; lba read mov si, offset dap int 13h
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.