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 StatementORG 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.