Problem mit Speicheraddressierung in Bootsector Programm.



  • Hallo,
    Ich bin relativ neu im gebiet der assembler Programmierung unterwegs.
    Ich verwend0e d0en yasm Assembler, der soweit ich's verstand0en habe, d0en nasm syntax verwend0et.
    Ich habe dieses kleine Bootsector Programm geschrieben und0 bekomme nicht
    wie erwartet d0en Schriftzug "Hello",0 sondern "H ll ".

    [BITS 16]
      ORG 0x7c00
      JMP _start
    
    Letters db "Hello", 10
    
    _start:
      MOV ah, 0x0e     ; Set register for interrupt 10 -> scrolling teletype BIOS routine
    
      MOV al, 0x48     ; Set the value of letter H to the register al
      INT 0x10         ; and call the interrupt 10 to print the letter on the screen
    
      MOV bx, Letters  ; Write the offset of "Letters" to the register bx
      MOV al, BYTE[bx] ; Write the byte at offset bx to al
      INT 0x10         ; Call the interrupt 10 to print the letter on the screen
    
      MOV al, 0x6C     ; Write the letter "l" to al
      INT 0x10
    
      MOV al, 0x6C     ; Write the letter "l" to al
      INT 0x10
    
      MOV al, BYTE[Letters + 4] ; Write the letter "o" to al
      INT 0x10                  ; Call the interrupt 10 to print the letter on the screen
    
    _loop:
      JMP _loop
    
    times 510 - ($-$$) db 0
    dw 0xAA55           ; Set the last two bytes to the “magic number”
                        ; to tell the BIOS this is a boot sector
    

    Kann mir jemand sagen wo der Fehler liegt?
    MfG
    Silvio



  • Irgend etwas ist mit Deiner Tastatur nicht in Ordnung. Hat Dir jemand einen fehlerhaften Keylogger untergejubelt?

    Dein Bootprogramm zeigt nicht "Hello", sondern - wie programmiert - "HHllo". Am besten machst du dir die Mühe, jeden englischen Kommentar in Deutsch zu übersetzen, eventuell macht es dann "klick".

    Mir ist das Lernziel dieses Beispiels etwas schleierhaft. Sag doch mal, welches Tutorial du verwendest bzw. woher du das Programm hast. Und auch, welchen Emulator (WinXP, Bochs, Qemu, VirtualPC, usw.) du benutzt.

    viele grüße
    ralph



  • Tut mir leid, aber... BULLSHIT!
    Mehr kann ich zu deinen Vorwürfen nicht sagen.
    Ich versuche mich in die OS Programmierung einzuarbeiten und gehe tutorials durch.
    Ich habe den Fehler selbst gefunden.
    Das segment register war nicht auf null gesetzt.
    Und die Kommentare sind auf englisch weil ich Kommentare immer auf englisch schreibe. Auch in meinen C/C++ codes.
    der Anfang muss so aussehen:

    [BITS 16]
      ORG 0x7c00
      XOR ax, ax       ; Set ax to zero
      MOV ds, ax       ; Set the segment register to zero
    

    Es ist wirklich nicht leicht sich in dieses themengebiet einzuarbeiten mit unvollständigen und teilweise veralteten tutorials und ellenlangen prozessordokumentationen von intel und amd.
    Auf bekloppte Anschuldigungen kann ich wirklich verzichten!

    MfG
    Silvio



  • Falls es jemanden interresiert, hier habe ich eine print rotiere geschrieben die einen beliebig langen string ausgibt.
    Wie schon gesagt bin ich ein ziemlicher newbie in assembler und os development und solche kleinen erfolge wenn auch noch so winzig spornen mich trotzdem an 😉

    [BITS 16]
      ORG 0x7c00
      XOR ax, ax       ; Set ax to zero
      MOV ds, ax       ; Set the segment register to zero
      JMP _print
    
      ; Addresses in 16bit real mode are calculated this way: segment register * 16 + offset
    
    Letters db "Hello World", 10, 0
    
    _start:
      MOV ah, 0x0e     ; Set register for interrupt 10 -> scrolling teletype BIOS routine
    
      MOV al, 0x48     ; Set the value of letter H to the register al
      INT 0x10         ; and call the interrupt 10 to print the letter on the screen
    
      MOV bx, Letters  ; Write the offset of "Letters" to the register bx
      ADD bx, 0x7c00   ; Add the offset this bootsector program is loaded to bx
      MOV al, BYTE[bx] ; Write the byte at offset bx to al
      INT 0x10         ; Call the interrupt 10 to print the letter on the screen
    
      MOV al, 0x6C     ; Write the letter "l" to al
      INT 0x10
    
      MOV al, BYTE[Letters + 3]     ; Write the letter "l" to al
      INT 0x10
    
      MOV al, BYTE[Letters + 4] ; Write the letter "o" to al
      INT 0x10                  ; Call the interrupt 10 to print the letter on the screen
    
    _print:
      MOV ah, 0x0e               ; Set register for interrupt 10 -> scrolling teletype BIOS routine
      MOV bx, 0x0                ; Use bx as a counter and initialize bx with zero
    _printLoop:
      MOV al, BYTE[Letters + bx] ; Load the letter at index bx from memory into al
      CMP al, 0x0                ; Compare al with zero
      JE  _loop                  ; If al is zero then exit the letter printing loop
      INC bx                     ; Increment bx
      INT 0x10                   ; Call the interrupt 10 to print the letter on the screen
      JMP _printLoop             ; Jump to the start of the letter printing loop
    
    _loop:
      JMP _loop                  ; Loop endlessly
    
    times 510 - ($-$$) db 0
    dw 0xAA55                    ; Set the last two bytes to the “magic number”
                                 ; to tell the BIOS this is a boot sector
    

    MfG
    Silvio



  • ADD bx, 0x7c00
    

    Was soll das machen ? Sicher dass das nötig ist?

    Und warum hast du in _start schon eine Ausgabe wenn du doch deine "Funktion" hast?

    Und ganz wichtig: Wenn du neu Assembly lernst warum dann gleich OS Development? Du weißt schon dass das zu dem Allerschwersten gehört was du so machen kannst?



  • DarkShadow44 schrieb:

    ADD bx, 0x7c00
    

    Was soll das machen ? Sicher dass das nötig ist?

    Und warum hast du in _start schon eine Ausgabe wenn du doch deine "Funktion" hast?

    Und ganz wichtig: Wenn du neu Assembly lernst warum dann gleich OS Development? Du weißt schon dass das zu dem Allerschwersten gehört was du so machen kannst?

    Zur ersten frage:

    ADD bx, 0x7c00
    

    Soweit ich's verstanden habe lädt das BIOS das Bootsectorprogramm in den Speicher an Adresse 0x7c00, die Speicheraddressierung beginnt aber bei Adresse 0x00. Deshalb muss der Wert 0x7c00 zur Adresse vom String addiert werden.
    Diese addition ist aber tatsächlich überflüssig, da ich mit dem Statement

    ORG 0x7c00
    

    dem Assembler mitteile, dass er bei der Addressberechnung ein Offset von 0x7c00 addieren soll.

    Zur zweiten Frage: Die zweite Funktion ist sozusagen die 2. Version der ersten Funktion.

    Zur dritten Frage: Ich lerne nur Assembler weil ich mich mit der Betriebssystem Programmierung beschäftigen möchte und nicht umgekehrt 🙂

    MfG
    Silvio



  • AbnormalWit schrieb:

    Ich lerne nur Assembler weil ich mich mit der Betriebssystem Programmierung beschäftigen möchte und nicht umgekehrt 🙂

    Dennoch würde ich empfehlen erst Assembler zu lernen, und dann mit der OS-Programmierung anzufangen. Im Usermode kann man Assembler wunderbar debuggen. 😉

    Auch bei einem OS kann man ja einiges in C lösen. Nur halt die ganzen Lowlevel Sachen nicht. Aber dazu gehört einen String mit Assembler auszugeben meiner Meinung nach nicht. 😉


Anmelden zum Antworten