Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Themen - misterunknown

Seiten: [1]
1
Moin,

um etwas Assembler zu lernen habe ich mir (mit einigen Anleitungen für ganz simple Bootloader) ein kleines bootfähiges Programm geschrieben, welches 3 Sachen macht:
  • einen Text ausgeben
  • in einer Schleife alle Tastatureingaben ausgeben
  • wenn ESC gedrückt wird noch einen Text ausgeben und beenden
Das funktioniert auch, bis auf dass die Enter-Taste nur einen Carriage Return ausgibt und keinen Zeilenumbruch macht. Das wollte ich ändern, indem ich prüfe, ob die Enter-Taste gedrückt wurde und wenn ja, erst der Zeilenumbruch ausgegeben wird (0x0A) und dann im Anschluss der Carriage Return (0x0D). Hier ein Ausschnitt:
Linebreak:
    mov ah,0x0E     ; Print-Funktion nutzen (0x0e)
    mov al,0x0A     ; Zeilenumbruch ausgeben
    int 0x10        ; Interrupt auslösen
    ret

Main:
    mov ah,00h      ; auf Tastendruck warten
    int 0x16        ; Interrupt auslösen
    cmp al,0x1B     ; ESC gedrückt?
    je  Ende        ;   => zum Ende springen
    push ax         ; ax sichern (al = 0x0D)
    cmp al,0x0D     ; Enter gedrückt?
    je  Linebreak   ;   => Zeilenumbruch (0x0A) ausgeben
    pop ax          ; ax wiederherstellen (damit sollte al wieder 0x0D sein)
    mov ah,0x0E     ; Print-Funktion einstellen
    int 0x10        ; Interrupt auslösen
    jmp Main        ; Main-Schleife

Das funktioniert nur so lange, bis man Enter drückt. Ist das der Fall wird nur der Zeilenumbruch ausgegeben (0x0A), und dann friert das Programm ein. Ich habe nach einigem hin- und herprobieren keine Idee mehr, was ich falsch mache. Ich habe auch keine Idee, wie ich das debuggen könnte, und hoffe jetzt, dass ihr mir helfen könnt.

Noch einige Informationen zu meinen Tools: Ich nutze zum Kompilieren nasm und zum Testen qemu:
$ nasm -f bin boot.asm -o boot.img
$ qemu-system-x86_64 -fda boot.img

Hier ist der vollständige Code:

;****************************************
; boot.asm - Einfacher Bootloader
;
; 2016 - marco@misterunknown.de
;****************************************

BITS 16             ; 16-Bit Real-Mode

org     0x7C00      ; Wir werden vom BIOS an diese Adresse geladen.


Start:  jmp Loader  ; Loader

msga    db  "Testausgabe",10,13,0
msgb    db  13,10,13,10,"Ende",13,10,0

;**************************************
; Funktionen
;**************************************

Print:
    lodsb           ; lädt das nächste Byte von SI nach AL
    or  al,al       ; ist AL null?
    jz  PrintDone   ; wenn ja, dann gehe zu PrintDone
    mov ah,0x0E     ; Print-Funktion nutzen (0x0e)
    int 0x10        ; Interrupt auslösen
    jmp Print       ; Rücksprungmarke aufrufen

PrintDone:
    ret

Linebreak:
    mov ah,0x0E     ; Print-Funktion nutzen (0x0e)
    mov al,0x0A     ; Zeilenumbruch ausgeben
    int 0x10        ; Interrupt auslösen
    ret

;**************************************
; Loader
;**************************************

Loader:
    xor ax,ax       ; schneller Weg um das Register zu nullen
    mov al,03h      ; in den Text-Modus wechseln (löscht gleichzeitig den Bildschirm)
    int 0x10        ; Interrupt auslösen

    mov si,msga     ; Nachricht in source-Register laden
    call Print      ; Print-Funktion aufrufen

;**************************************
; Hauptschleife
;**************************************

Main:
    mov ah,00h      ; auf Tastendruck warten
    int 0x16        ; Interrupt auslösen
    cmp al,0x1B     ; ESC gedrückt?
    je  Ende        ;   => zum Ende springen
    push ax         ; ax sichern (al = 0x0D)
    cmp al,0x0D     ; Enter gedrückt?
    je  Linebreak   ;   => Zeilenumbruch (0x0A) ausgeben
    pop ax          ; ax wiederherstellen (damit sollte al wieder 0x0D sein)
    mov ah,0x0E     ; Print-Funktion einstellen
    int 0x10        ; Interrupt auslösen
    jmp Main        ; Main-Schleife

Ende:
    mov si,msgb
    call Print
    cli             ; Interrupts leeren
    hlt             ; System anhalten

times 510 - ($ - $$) db 0   ; Das Programm muss 512 Bytes groß werden. Dazu wird mit Nullen aufgefüllt.
                            ; 510 kommt daher, weil hinten noch die 2 Byte lange Signatur folgt.
dw  0xAA55          ; Signatur des Bootloaders

; vim: syn=nasm
Seiten: [1]

Einloggen