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.


Log in to reply