Print funktion in bootloader lässt sich nur einmal verwenden
-
Hallo,
Mein program ist ein bootsector program also ein bootloader (besser gesagt, das soll es einmal werden). Bis jetzt habe ich nur ein paar Funktionen zum ausgeben von text im "text video memory" mode. Alles noch in 16bit (zu 32bit komme ich noch).
Mein problem hier ist, dass sich die print funktion nur einmal aufrufen lässt und sich danach (glaube ich zumindest) aufhängt.[ORG 0x7c00] ; The bootsector program will start at 0x7c00 and end at 0x7e00 (512bytes) XOR ax, ax ; Set ax to zero MOV ds, ax ; Set the data segment to address 0x0000 MOV ss, ax ; Set the stack segment to address 0x0000 MOV bp, 0x8000 ; Set the stack base pointer shortly after the end of the bootsector program MOV sp, bp ; The stack will grow in negative direction MOV ax, 0xb800 ; Set the text video memory address MOV es, ax ; Set the extra segment address to text video memory JMP begin TestString DB "Hello Computer!", 0 TestString2 DB 'Computer!', 0 begin: MOV cx, 0x0202 MOV dx, TestString2 CALL printString2 MOV cx, 0x0000 MOV dx, TestString CALL printString2 hang: JMP hang ; ------------------------------------------------------------- ; 0x0 = black 0x1 = blue ; 0x2 = green 0x3 = cyan ; 0x4 = red 0x5 = magenta ; 0x6 = brown 0x7 = white ; 0x8 = grey 0x9 = bright blue ; 0xA = bright green 0xB = bright cyan ; 0xC = bright red 0xD = bright magenta ; 0xE = bright yellow 0xF = bright white ; ; In text video memory mode the screen resolution will be ; 80 columns x 25 lines. ; This function will print a single letter to text video memory ; ; cx = position (low=y heigh=x) ; dx = letter (low=letter heigh=attribute) printLetter2: PUSHA ; Save the state of all registers to the stack MOV ax, WORD 0 ; Set ax to zero MOV al, 160 ; 80 columns = 160 bytes (2bytes per letter) MUL cl ; Multiply y position with the number of columns MOVZX bx, ch ; Save the x position in the full bx register SHL bx, 1 ; Multiply the x position with two because every letter uses 16bit MOV di, 0 ; Go to the begin of video memory ADD di, bx ; Add x offset ADD di, ax ; Add y offset MOV WORD[es:di], dx ; write letter to video memory POPA ; Restore the state of all registers RET ; Return ; ------------------------------------------------------------- ; Print a string to text video memory ; cx = position to print to (low=y heigh=x) ; dx = string pointer (low=letter heigh=attribute) printString2: PUSHA ; Save the state of all registers to the stack MOV ax, WORD 0 ; Use ax as a counter variable printLoopBegin2: PUSH dx ; Save the address of the string to the stack MOV bx, dx ; Save address of the string to be printed in bx ADD bx, ax ; Add the counter value to the string address MOV dl, BYTE[bx] ; Save the current letter to dl MOV dh, 0x1F ; Set the color attribute of the current letter to dh CMP dl, BYTE 0 ; Compare the current letter with zero JE printLoopEnd2 ; If the current letter is zero then ; jump to the end of the printing loop CALL printLetter2 ; Print the current letter to the screen INC ch ; Increment the x position INC ax ; Increment the counter POP dx ; Retrieve the address of the string JMP printLoopBegin2 ; Jump to the begin of the loop printLoopEnd2: POPA ; Restore all registers RET ; Return ; ------------------------------------------------------------------ ; TIMES 510-($-$$) DB 0 ; Fill the file til byte 510 with zeros DB 0x55 ; Set byte 511 to the magic bootsector number DB 0xAA ; Set byte 512 to the magic bootsector number
Vielleicht habe ich den stack falsch initialisiert oder vergessen irgend ein register zu setzen. Ich finde den Fehler irgendwie nicht. Ich habe die print funktionen schon zweimal neu geschrieben, mit dem selben Ergebnis. Der text lässt sich nur einmal ausgeben.
Ich teste den code nicht im emulator sondern auf einem netbook mit intel atom cpu.MfG
Silvio
-
Nach Zeile 79 fehlt ein
'pop dx'
, siehe Zeile 65 und 72.
-
osdt schrieb:
Nach Zeile 79 fehlt ein
'pop dx'
, siehe Zeile 65 und 72.Hey, danke!!
Das war der Fehler.
Ich habe vollkommen übersehen, dass dx noch auf dem stack ist nachdem aus der schleife gesprungen wurde.Danke nochmal
-
Es würde wohl reichen, das 'PUSH dx' vor 'printLoopBegin2:' zu setzen und dann auch nur ein 'POP dx' nach 'printLoopEnd2:' zu haben.
-
popdx schrieb:
Es würde wohl reichen, das 'PUSH dx' vor 'printLoopBegin2:' zu setzen und dann auch nur ein 'POP dx' nach 'printLoopEnd2:' zu haben.
Nein, das reicht doch nicht wegen 'MOV bx, dx' in der Schleife.
-
popdx schrieb:
popdx schrieb:
Es würde wohl reichen, das 'PUSH dx' vor 'printLoopBegin2:' zu setzen und dann auch nur ein 'POP dx' nach 'printLoopEnd2:' zu haben.
Nein, das reicht doch nicht wegen 'MOV bx, dx' in der Schleife.
Es würde auch keinen Sinn ergeben, da save/restore von dx bereits durch PUSHA/POPA abgedeckt ist.