Autor Thema: Fehler/Ungenauigkeit in der ersten Ausgabe ???  (Gelesen 14497 mal)

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« am: 03. August 2004, 14:40 »
Hi,

ich habe mal ne Frage zu dem Bootloader in der ersten Ausgaeb eueres Magazins. Ich versuch grad alles mehr oder weniger richtig zu verstehen und auch die ganzen Befehle nachzuschauen (BIOS INterrupts usw...) und bin jetzt auf was gestoßen was ich nirgendswo gefunden habe usw...

Der Code ist deswegen nicht falsch, das ist mir auch klar, schließlich funktioniert er ja :)

und zwar folgendes:

; Diskdrive reset (Interrupt 13h, 0)
push ds         ; Sichere DS
mov ax, 0         ; Die gewünschte Funktion (reset)
mov dl, [bootdrv]     ; Dieses Laufwerk ist gewünscht
int 13h         ; Den Interrupt ausführen
pop ds             ; DS wiederherstellen
jc load         ; Geht nicht? -> Noch mal!
load1:
mov ax,0x1000         ; ES:BX = 10000
mov es,ax
mov bx, 0


Ich habe mir verschiedene Interrupt Listen durchgeschaut und bin jetzt darauf gestoßen, dass im Prinzip das setzen von ax auf 0 nicht ganz korrekt ist. Der Funktion reicht es schon aus wenn nur ah auf 0 gesetzt wird, so steht es auch in den agnzen Referenzen in denen ich nachgeschaut habe. Mir ist klar dass das Register AH ein Teil von AX ist..

Wollte ich nur mal so erwähnen

aber dennoch find ich euer Mag echt sehr gut gemacht !!

Grüße
Vamp

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #1 am: 03. August 2004, 15:12 »
Salop gesagt ist das völlig wurscht;-). Ob ich nun nur AH oder AX 0 Setzt ist egal. Es beeinflusst den Interrupt in keinster Weise und Performance geht auch nicht drauf, da der Prozessor 32Bit gleichzeitig übertragen kann, das bewirkt garnichts, wir hätten auch mov eax,0 machen können da wäre im Prinzip genau das selbe rausgekommen.
Persönliche Anmerkung: Ich selbst verwende nie mov **,0 sondern immer xor **,** dadurch wirds auch Null,sieht Professioneller aus find ich, und auf älteren Prozessoren wird der xor Befehl schneller ausgeführt, also braucht weniger Takte. Aber ist nur persönlicher Geschmack
Generell hast du irgendwo schon Recht das am besten möglichst genau nur die Register angesprochen werden sollten die nötig sind, aber das ist fast immer egal. Also das ist kein Fehler und auch keine Ungenauigkeit, sondern einfach naja sagen wir Willkür.
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 03. August 2004, 15:18 »
ja hast recht :) Verwende auch lieber XOR ah,ah, versteht net gleich jeder *gg* und das ist ja acuh nen Grund Assembler zu proggen *löl*

War ja nur ne Anmerkung sollte kein Angriff sein :) Aber es könnte ja sein, dass ich in meinem Bootloader in al den wichtigsten Wert speichere den es gibt *ok sehr abstrakt diese Theorie*

Ist mir halt aufgefallen, da ich mir grad die kompletten interrupt Tabellen anschaue.

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #3 am: 03. August 2004, 15:19 »
Wo willst du schon im Bootloader Ultra wichtige DAten her haben?;-)
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #4 am: 03. August 2004, 17:38 »
Das ist immer ansichtssache.

In jeder Sprache (und gerade in ASM) kann man "sehr schmutzig" programmieren.

Ich persöhnlich finde xor ax, ax auch "schmutzig" da es einfach nicht so einfach zu lesen ist wie "mov ax, 0".

xor ist halt schneller und benötigt auch weniger Bytes an speicher, weshalb diese Variante oft benutzt wird.

Gerade aber in Beispielcode halte ich es für wichtig das man "lesbaren" Code schreibt.
Der Performancegewinn ist minimal und ist im Endeffekt eher ein Nachteil wenn Leute die noch nicht so fit sind es nicht lesen/verstehen können.
----------------------
Redakteur bei LowLevel

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #5 am: 04. August 2004, 10:02 »
Ich sagte das ich diese Variante vorziehe, ich zwinge ja keinen dazu. Ich denke mal schon dass ich relativ fit in ASM bin;)
Aber schau mal, da ASM sowieso die wenigsten können, kann man doch gleich so programmieren oder? Versteht so oder so kaum jemand. Und manchmal kann ein eingesparter Byte wichtig sein, zb im Bootsektor;)
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 04. August 2004, 10:08 »
also ich denk es ist net so schlimm wenn man die XOR Variante wählt. Habe es auch ziemlich schnell kennengelernt und falls man es nicht weiß was diese Anweisung macht, dann kann ja auch entweder bei ner Suchmaschine schauen, oder man schreibt sich die logische Verknüpfung auf, man sollte die eh sich anschauen und dann versteht man das denk ich auch. Ich denke nen Anfänger in Assembler freut sich sogar wenn er mitbekommt das er mit xor ax,ax was zurücksetzen kann und dies schneller ist als mov ax,0, zumindest habe ich mir das sofort gemerkt :) Wobei ich ja immer noch nen Anfänger bin :-/

Grüße
Morti

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 05. August 2004, 10:29 »
So, habe nochmal ne kleine Frage zu euren Bootloader *gg*

1)

; Sektoren lesen (Interrupt 13h, 2)
mov ah, 2 ; Funktion 2 (Lesen)
mov al, 5 ; Lese 5 Sektoren
mov cx, 2 ; Cylinder=0, Sector=2
mov dx, 0 ; Head=0, Laufwerk=0
int 13h ; ES:BX = Daten vom Laufwerk
jc load1 ; Fehler? Noch mal!
mov si,loadmsg
call putstr ; Meldung ausgeben
retn

ihr setzt hier dx einfach auf 0, im Prinzip ist es ja ähnlich wie das, was ich schon oben geschrieben habe, aber meine Frage ist, wenn ihr das Laufwerk auf 0 setzt ist das zwar nicht falsch, aber auch nur wenn es sich um ein Diskettenlaufwerk handelt oder ???
wäre es nicht geschickter so:
mov dl,[bootdrv]
mov dh,0

oder ist das Absichtlich ?? (kenne mich halt (noch) net soo toll aus und will halt ne Bestätigung ob meine Ansicht true or false ist )

2)
;Springe zu diesem Kernel
mov ax, 0x1000 ; Die Adresse des Programms
mov es, ax ; Segmentregister updaten
mov ds, ax
push ax
mov ax, 0
push ax
retf

kann es sein dass die Zeilen:
mov es, ax ;und
mov ds, ax

unnötig sind und nicht gebraucht werden, da wir die Segment und Offsetadresse auf den Stack pushen ??


Vielen Dank und sorry, dass ich mit meinen tollen kleinigkeiten nerv *gg*

Grüße
Morti

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 05. August 2004, 10:45 »
Noch ne Frage, warum resettet ihr eigentlich beim Bootloader das Laufwerk ?? Ist das notwendig oder nicht ???

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #9 am: 05. August 2004, 10:59 »
Nicht umbedingt.
Ich habs bei mir nicht drin und es funzt trotzdem :)
----------------------
Redakteur bei LowLevel

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 05. August 2004, 11:07 »
hm.. worauf antwortest du jetzt ???
weiß dass der Code an für sich net falsch ist und er auch ohne größere Probs läuft, wollte nur ein paar anmerkungen machen und vielleicht etwas schlauer werden :)

mastermesh

  • Beiträge: 341
    • Profil anzeigen
    • http://www.kostenloser-laptop.de/
Gespeichert
« Antwort #11 am: 05. August 2004, 11:12 »
Zur Frage mit DX:

Ist tatsächlich eine kleine Ungenauigkeit von mir. Allerdings glaube ich kaum, dass jemand den Bootloader auf einer Festplatte installieren würde... deshalb hab ich einfach mal pauschal das Bootlaufwerk auf 0 gesetzt.

Zur Frage mit DS und ES:

Wir nehmen dem Kernel ein wenig Arbeit ab, wenn wir schon im Voraus DS und ES richtig setzen. Immerhin haben wir ja 512 Bytes an Code, die irgendwie verbraucht werden müssen ;) (-> siehe 512-Byte-Contest)

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 05. August 2004, 11:32 »
ok schonmal vielen Dank für die Antworten :)

dann schein ich ja zumindest den Bootloader jetzt komplett auseinandergenommen zu haben *gg*

Mal ne Frage zum ES, wird das wirklich gesetzt weil im Prinzip ist das doch nur zuständig für Daten die keinen Platz mehr im DS haben, oder irre ich mich da ?

ach ja und wie sieht das mit diesem Code aus:

; Diskdrive reset (Interrupt 13h, 0)
push ds ; Sichere DS
mov ax, 0 ; Die gewünschte Funktion (reset)
mov dl, [bootdrv] ; Dieses Laufwerk ist gewünscht
int 13h ; Den Interrupt ausführen
pop ds ; DS wiederherstellen
jc load ; Geht nicht? -> Noch mal!

wird der benötigt oder muss das gemacht werden ? weil bei mir scheint es auch ohne diese "Funktion" zu gehen.

Danke

Grüße
Morti

Another Stupid Coder

  • Beiträge: 749
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 05. August 2004, 12:21 »
Ähm...TeeJay hat doch schon (4 Posts über meinem hier) gepostet das er das Reseten des Diskettenlaufwerks nicht drinnen hat und es trotzdem läuft.

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #14 am: 05. August 2004, 12:26 »
TJ meint sicherlich das der DiskettenReset nicht zwingend notwendig ist^^
Das es wird zum Beispiel bei stos gebraucht das verwendet die Kombination es:edi zur Addressierung.
Und das hier:
2)
;Springe zu diesem Kernel
mov ax, 0x1000 ; Die Adresse des Programms
mov es, ax ; Segmentregister updaten
mov ds, ax
push ax
mov ax, 0
push ax
retf

find ich persönlich äusserst lustigen Code *g* aber den hab ich bei mir garnicht in use^^
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

mastermesh

  • Beiträge: 341
    • Profil anzeigen
    • http://www.kostenloser-laptop.de/
Gespeichert
« Antwort #15 am: 05. August 2004, 12:27 »
Zitat
Vampire posteteMal ne Frage zum ES, wird das wirklich gesetzt weil im Prinzip ist das doch nur zuständig für Daten die keinen Platz mehr im DS haben, oder irre ich mich da ?
Nicht wirklich. ES kannst du für alles mögliche verwenden. Wenn du zum Beispiel die Interrupt-Table beschreiben willst, brauchst du Zugriff auf Segment 0 und das kannst du wunderbar mit ES lösen...

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 05. August 2004, 12:44 »
Roshl was verwendest du persönlich dann für ne Routine ?? Würd mich mal interessieren :)

danke

Grüße
Vamp

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #17 am: 05. August 2004, 14:05 »
Naja ich hab ein komplett anderen Aufbau;) Ich habe die GDT nicht im kernel mit drinstehn und sowas, Die GDT schreibe ich an die addresse 0x20000
die IDT nach 0x30000 der Kernel nach 0x10000  danach kommt A20 und PIC umproggen, dann gdtr und idtr Register setzten das cr0 verändern und dann ein jmp 8:0 (der die Basis 0x10000 hat also ich initiallisiere den pm schon im bootloader im kernel mache ich dann noch einen jmp 18h:10007h also in das Segment das von 0 anfägt und den Startdeskriptor baue ich dann als Stacksegment um;) und dann kommt der C-Kernel;)
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 05. August 2004, 15:01 »
Ok, jetzt ist das passiert was ich mir gedacht habe.. Buffer Overflow, versteh nix mehr :-(
aber egal, irgendwie werd ich mich jetzt dennoch durch alles kämpfen...
allein schon die ganzen Abkürzungen..

locate GDT, IDT usw...

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #19 am: 05. August 2004, 15:37 »
Kann dirs ja erklärn wenn du willst ICQ oder MSN Messi steht alles im Profil;)
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

 

Einloggen