Autor Thema: Stack richtig initalisieren  (Gelesen 6110 mal)

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« am: 27. March 2006, 20:25 »
Hallo,

ich habe ein Problem mit meinem Stack
mein Betriebssystem besteht aus einem 16 Bit Assembler Bootloader und einem 16 Bit assembler Kernel (der allerdings mit ld gelinkt werden muss, damit ich später einmal C einbauen kann)

wenn ich mein Os starte läuft der Bootloader problemlos durch,
lädt den Kernel, aber dann hängt der computer sich auf,
dann hab ich das ganze noch in Bochs probiert, der sagt dazu:
"IRET: top 6 bytes of stack not within stack limits"

deswegen denke ich, ich habe den Stack falsch initalisiert
hier der Bootloader:

org 7c00h

;Stackinitalisierung

cli
mov ax, 9000h
mov ss, ax
xor sp, sp
sti

;Stackinitalisierung Ende

jmp main

readbr:
mov ah, 02h   ;fest
mov al, 01h   ;Anzahl
mov ch, 00h   ;Spur
mov cl, 02h   ;Sektor
mov dh, 00h   ;Kopf
mov dl, 00h   ;Laufwerksnummer
mov bx, 1000h
mov es, bx    ;Segment
mov bx, 0000h ;Offset
int 13h
ret

main:
call readbr
mov ax, 1000h
push ax
mov ax, 0000h
push ax
retf

int 19h
TIMES 510-($-$$) DB 0
SIGNATURE DW 0xAA55


es macht auch keinen Unterschied wenn ich die Stackinitalisierung weglasse, immer die gleiche Fehlermeldung

hier noch der code vom Asm-Kernel, auch wenn ich nicht glaube das es an dem hängt:

global start
start:
cli
mov ax, 1000h
mov ds, ax
mov es, ax
sti
mov si, hello ;hier
int 19h
hello db "Kernel started", 13, 10, 0
TIMES 512-($-$$) DB 0


ohne die Zeile "mov si, hello" funktioniert das ganze sogar

ich seh leider auch keinen zusammenhang zwischen der Zeile und dem Stack, auf den Stack bin ich nur durch Blochs Fehlermeldung gekommen

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 27. March 2006, 21:51 »
Hallo,

ein Stack "wächst" von oben nach unten. Ich denke mal daran liegt der Fehler.

Das heißt du solltest ss:(e)sp an einer möglichst hohen Adresse initialisieren.
also z.B. auf 0x9000:0xE000. Das sollte so ziemlich das höchste sein was du addressieren kannst.

Gruß, GhostCoder
A man, a legend!

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 28. March 2006, 09:31 »
aber ich initalisiere doch mit

cli
mov ax, 9000h
mov ss, ax
xor sp, sp
sti


das ist doch dann 9000:0000 das muss doch locker reichen
oder muss ich den im Kernel nochmal initalisieren?

ich hab das ganze aus dem Tutorial, von Heft 1
die einzige Änderung ist
xor sp, sp
statt
mov sp, 0
und das ist ja das gleiche

EDIT:

ich hab mir jetzt mal den Inhalt der Register nach dem absturz angeschaut, dabei sind mir 2 Sachen aufgefallen:

1.ds steht auf 0, obwohl ich das ja extra auf 1000h gesetzt hab
wenn ds nicht auf 1000 steht funktioniert das ganze natürlich nicht
da die Adresse dann falsch, die ja mit ds:si angegeben wird

2.in si seteh 19cd0000
der Wert kommt mir aber ziemlich hoch vor
kann sein das die letzten 0en nicht mitgerechnet werden
aber mein kompletter Asm-Kernel ist ja nur 200h Bytes lang
wie kommt der dann auf so einen hohen Wert?

dann frag ich mich noch was "mov si, hallo" überhaupt mit dem Stack zu tun hat

Außerdem hat Bochs noch folgendes ausgegeben:
   base    limit
CS 000f0000 0000ffff
DS 00000000 0000ffff
SS 00090000 0000ffff
ES 00010000 0000ffff
FS 00000000 0000ffff
GS 00000000 0000ffff


nach den Werten sind CS, SS und ES ja schon weit aus dem Limit raus

EDIT2:

komisch jetzt klappt es, ich hab sp einfach statt mit 0 mit e000 initalisiert
aber im tutorial wurde doch auch 0 benutzt, warum geht das dann nicht?

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 28. March 2006, 14:27 »
ja, der sp muss ,glaube ich, hoch sein, weil der stack nicht aus seinem stacksegment heraus kann. das heißt, wenn ss:sp 9000:0000 ist, kann der stack nicht weiter nach unten wachsen, weil sein segment zu ende ist. warum das mit sp auf 0 in heft 1 steht weiß ich auch nicht. ich glaube sogar, das hatte bei mir funktioniert. deshalb bin ich ehrlich gesagt auch etwas verwirrt.

die unterste ausgabe von bochs ist so gemeint: lineare adresse des segmentstarts und größe-1 des segments. im realmode ist die größe eines segments immer 0x10000, deshalb steht da immer 0xFFFF. und die lineare startadresse eines segments ist immer der wert im segmentregister mal 0x10.  deshalb steht bei ss zum beispiel 90000 anstelle von 9000.

cs hat also am ende den wert 0xf000. das heißt normalerweise, dass bios-code ausgeführt wird. das könnte auch erklären, dass das ds auf 0 ist. bin mir nicht sicher, aber es wäre ja möglich, dass gerade code von woanders gebraucht wird und das bios ds entsprechend initialisiert hat.

was "mov si, hello" mit dem stack zu tun hat, weiß ich auch nicht.

si sind nur die niederen (rechten) 2 byte von esi. also 4 hexadezimalstellen. eigentlich dürften also nur die vier nullen zählen. bin mir da aber jetzt nicht wirklich sicher.

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 28. March 2006, 16:27 »
Das SP hoch sein sollte, meinte ich doch damit. Dachte das wäre klar :)

Gruß
A man, a legend!

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 28. March 2006, 17:51 »
das komische ist das es im tutorial eben auf 0 ist
und das tutorial funzt ja

deswegen hab ich den Fehler auch nicht gefunden
ich hab schon überlegt dass das eigentlich höher sein müsste
aber im tutorial wars halt auf 0

 

Einloggen