Autor Thema: Datendeklaration  (Gelesen 5559 mal)

Limbo

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« am: 31. July 2004, 01:01 »
Moin :-)

Ich hab da wohl ein kleines Verständnisproblem, aber erstmal der Code (stammt aus der 1. Lowlevel-Ausgabe, Bootloader->Kernel.asm) :

mov ax, 1000h ; Segmentregister updaten
    mov ds, ax
    mov es, ax
       
start:
    mov si, Msg
putstr:
    lodsb             ; Byte laden
    or al,al
    jz short putstrd  ; 0-Byte? -> Ende!

    mov ah,0x0E       ; Funktion 0x0E
    mov bx,0x0007     ; Attribut-Byte (wird nicht benötigt)
    int 0x10          ; schreiben
    jmp putstr        ; Nächstes Byte
putstrd:          
    jmp ende
   
    Msg    db    "Kernel16",13,10,0
       
ende:

Hab's ein wenig gekürzt (kein getkey und reboot)
Mir geht's nur um folgendes. So wie der Code da steht, lässt er sich kompilieren und mit dem Lowlevel-Bootloader starten. Es wird nur "Kernel16", also der String ausgegeben. Jetzt mein Problem : Wenn ich msg vor start: oder kurz dahinter deklariere lässt sich das auch kompilieren, wenn dieser "Kernel" geladen wird erscheint der String aber nicht auf dem Moni !?

Der Kernel wird doch an 1000h geladen und das DS auf diese Adresse gesetzt.
So viel weiß sollten die Daten im Datensegment stehen, und das wäre doch auch
kurz vor / hinter start: der Fall ... ??

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #1 am: 31. July 2004, 02:14 »
Ja. Aber du musst das so sehen.

Der Prozessor fängt an den Code von oben her abzuarbeiten.
Dabei liest er Befehl für Befehl ein und führt ihn aus.

Wenn du nun die MSG vor oder hinter Start positionierst, dann versucht der Prozessor diesesn String als Befehl einzulesen und zu interpretieren, was aber fehlschlägt, da es ja kein Befehl ist.
Folglich kommt er ins schludern und das Programm is futsch.

Der String selbst steht streng genommen direkt im Code drin.
Da er aber (siehe oben) ans Ende des Codes gepackt ist, kommt der Prozessor nie soweit, das er diesen als Befehl einlesen würde und zu interpretieren würde.


Änder den Code von oben wie folgt ab:

mov ax, 1000h ; Segmentregister updaten
mov ds, ax
mov es, ax

jmp Start

Msg db "Kernel16",13,10,0

start:
mov si, Msg
putstr:
lodsb ; Byte laden
or al,al
jz short putstrd ; 0-Byte? -> Ende!

mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Attribut-Byte (wird nicht benötigt)
int 0x10 ; schreiben
jmp putstr ; Nächstes Byte
putstrd:
jmp ende


Jetzt wird der Code laufen, da wir mit dem "jmp Start" über den String hinwegspringen und der Prozessor somit nicht dazu kommt den String als Befehl zu lesen.
----------------------
Redakteur bei LowLevel

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #2 am: 31. July 2004, 12:13 »
Nur hat man so ein unnötiges jmp drin, was ganz pingelig gesehn zu Performenceverlust führt. Zugegeben sehr kleinlich gesehn aber theoretisch ist es so^^ In der Zeiten der GHz CPU's fällt sowas nur leider keinem mehr auf. Aber mal angenommen wir hätten ein Multitasking OS und der Taskhandler hat immer solch einen jmp drin (warum auch immer) würde je nach dem wie man den PIC programmiert hat, jedesmal beim Timerinterrupt (womit der Taskhandler ja meistens ausgelöst wird) ein unnötiges jmp ausgeführt. Bei einem ordentlichen Multitask OS passiert das viele 1000 mal, oder gar noch viel mehr. Diese 1000e von Taktzyklen kann man ja (insbesondere bei OS's die ja die Grundlage von allem späteren sin) anders verwenden. Das was im OS verschwendet wird steht den Tasks letztendlich auch nicht mehr zur Verfügung.
Ok die meisten werden sich zwar nicht mit Multitask beschäftigt haben und haben wohl keine Ahnung was ich erzähle, aber naja was ich damit sagen will ist, dass man sich von Anfang an einen möglichst Performencesparenden Stil angewöhnen sollte. Meistens ist man zwar froh, dass es überhaupt so läuft wie man will, aber man sollte die Geschwindigkeit nicht ganz ausser Betracht lassen.
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

chr15

  • Beiträge: 279
    • Profil anzeigen
    • http://www.clinux.de.vu
Gespeichert
« Antwort #3 am: 31. July 2004, 12:45 »
Dieses Problem kann man einfach lösen, indem man für Daten und Code und Stack verschiedene Segmente nimmt. So wird es im PMode bei den meisten Betriebssystemen auch gemacht...

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #4 am: 31. July 2004, 14:07 »
Ja aber selbst wenn du extra Segmente nimmst, hast du die Daten hier trotzdem im Code stehen.

Am besten man plaziert die Daten einfach an den Ende des Codes.
Da sind sie gesammelt und sofern man keinen Bug programmiert hat, werden diese Daten von der CPU auch nie als Befehl in betracht gezogen.
----------------------
Redakteur bei LowLevel

 

Einloggen