Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Another Stupid Coder am 17. August 2004, 12:37
-
Hallo,
Ich habe hier einen kleinen Bootloader wie man ihn in fast jedem Tutorial finden kann und frage mich nun warum der Text keine Farbe (grün auf schwarz) hat.
Hier ist der Code:
[bits 16]
org 0x7C00
main:
mov ax, 0x0000
mov ds, ax
mov si, HelloWorld
call PutStr
jmp $
;------------------------
; Funktionen
;------------------------
PutStr:
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x20 ; Farbe
.nextchar
lodsb
or al, al
jz .return
int 0x10
jmp .nextchar
.return
ret
;------------------------
; Data
;------------------------
HelloWorld db 'Hello, World!', 13, 10, 0
times 510 - ($ - $$) db 0
dw 0xAA55
-
hm.. soll nen Fehler von Bochs sein *gg*
Probier mal diese direkte ausgabe von nem A aus:
mov ax,0xb800
mov gs,ax
mov word [gs:0],0x641
Grüße
Vamp
-
es funtioniert aber nicht nur mit bochs nicht...
-
jep liegt echt an Bochs, ist nen Fehler, habe schon öfters darüber was gelesen und habe mich am Anfang auch sehr gewundert, dass das nicht läuft. Bochs ist halt zum Testen ganz nett, aber es ersetzt halt net das richtige Laden über das BIOS vom PC..
-
Ãhm...mag sein aber bei mir läufts auch mit nem echten Reboot nicht und laut nem Bekannten auch mit VM-Ware nicht...
-
hm...
da es bei mir auch net so lief, weiß ich es auch net ganz genau, aber warum versuchst du net die Funktion die ich oben erwähnt habe ??
hier mal nen kleiner Ansatz zu ner Print Methode mit Hilfe dieser Methode:
mov si, mesg
mov ax,0xb800 ;dies ist der Video Port
mov gs,ax ;port nach GS
mov al, [si] ;position des ersten Buchstaben
next:
mov ah, 6 ;Farbe setzen
cmp al,0 ;auf 0 vergleichen
je ende
mov word [gs:0],ax ; ausgeben
mov al, [si+1] ;nächstes Zeichen laden
jmp next ;spring zum nächsten
ende
leider funktioniert die noch net komplett, aber damit wird die Farbe richtig angezeigt. Müsste man nur noch schauen, wie man den Cursor um eine Position setzt, geht zwar auch mit dem Interrupt 10h, aber müsste auch irgendwie ohne Interrupt gehen :)
vielleicht hilfts, werd ncoh weiter an ner Lösung basteln, habe aber grad net soo viel Zeit :/
Grüße
Morti
-
so da ich meinen Eintrag leider nicht mehr ändern kann muss ich halt nen neuen post abschicken :/
also habe noch etwas rumgespielt damit, und habe jetzt folgendes:
mov si, mesg
mov al, [si]
mov bx,0xb800 ; Load gs to point to video memory
mov ah, 6
next:
cmp al,0
je ende
mov gs,bx ; We intend to display a brown A in real mode
mov word [gs:0],ax ; display
inc bl
inc si
mov al, [si]
jmp next
ende:
dieser Code klappt soweit gut, dass er den kompletten String ausgibt, das einzige Prob ist dass der Zeichenabstand etwas zu lang ist :( wenn das jemand noch rausbekommt, wäre es cool.
Die Deklaration des Strings sollte so geschehen:
mesg db "MY MESSAGE",0
Grüße
Morti
-
@vampire
ich weiß warum du so einen großen abstand hast! Das Problem müsste sich wie folgt lösen lassen:
folgende codezeilen....
mov word [gs:0],ax ; display
inc bl
bilden das problem! wenn du bl incrementierst, inkrementierst du damit gs (siehe deinen code). du springst also ein segmentregister, und damit 16 byte weiter. klar, das dann die zeichen einen zu großen abstand voneinander haben.
und noch was... die zeile mov al, [si]
in der 2. und vor-vorletzten zeile ist auch doppelt gemoppelt. ist zwar kein fehler, aber muss ja nicht sein...
Naja, hier der geänderte code! hab ihn nicht getestet, müsste aber funzn :)
cld ;direction-flag löschen - um fehler bei schreibrichtung zu vermeiden
;denn man weiss ja nie ;) ...
mov di, 0 ;nur der hier wird verändert....
mov si, mesg
mov bx,0xb800 ; Load gs to point to video memory
mov gs,bx ;diese zeile nach oben, da gs sowieso nicht mehr verändert wird...
mov ah, 6 ;6 bedeutet braun!! - eine wichtige notitz :)
next:
mov al, [si]
cmp al,0
je ende
mov word [gs:di],ax ; display
inc di ;2x inc, da wir es ja mit words zu tun haben....
inc di
inc si
jmp next
ende:
cu AnimeSpirit
-
hi Anime
danke für die Antwort :)
ja funktioniert so einwandfrei.
Klar das mit dem al, [si] war zweimal drin, sowas passiert bei soviel Chaos *gg*
noch ne Frage, weißt du wie man noch hinbekommt, dass 13,10 nen Zeilenumbruch gibt ?? aber wenns geht ohne zusätzlichen Programmcode, ansonsten werd ich mir noch was dazuproggen
Grüße
Morti
-
Das sollte einfach so gehen das 13 das ASCII Zeichen für (in C) '\r' ist und 10 das ASCII Zeichen für '\n' ist soweit ich weiss also:
HelloWorld db 'Hello World',13,10,0
-
Danke, ihr beiden! Farbig ist der Code jetzt nur habe ich wieder 2 kleine Probleme:
1. Der Zeilenumbruch klappt nicht.
2. Das erste Zeichen (im code das "H") wird nicht angezeigt.
[bits 16]
org 0x7C00
main:
mov ax, 0x0000
mov ds, ax
mov si, HelloWorld
call PutStr
jmp $
;%include "functions.inc"
;------------------------
; Funktionen
;------------------------
PutStr:
cld ;direction-flag löschen - um fehler bei schreibrichtung zu vermeiden denn man weiss ja nie ;) ...
mov di, 0 ;nur der hier wird verändert....A
mov bx, 0xb800 ; Load gs to point to video memory
mov gs, bx ;diese zeile nach oben, da gs sowieso nicht mehr verändert wird...
mov ah, 6 ;6 bedeutet braun!! - eine wichtige notitz :)
next:
mov al, [si]
cmp al, 0
je ende
mov word [gs:di],ax ; display
inc di ;2x inc, da wir es ja mit words zu tun haben....
inc di
inc si
jmp next
ende:
ret
;------------------------
; Data
;------------------------
HelloWorld db 'Hello, World!', 13, 10, 0
times 510 - ($ - $$) db 0
dw 0xAA55
(ich habe den Code übrigens nur reinkopiert um ihn mal zu testen.
-
Sorry, das mit dem 1. char war mein Fehler! Das stimmt schon nur der Zeilenumbruch noch nicht.
-
hm... also habe mal etwasw rumprobiert, also ne Zeile hat bei mir 150 Zeichen, weiß aber leider net wie das bei Dir ist, glaub das ist auflösungsabhängig, hier nochmal etwas Code
cld ;direction-flag löschen - um fehler bei schreibrichtung zu vermeiden
;denn man weiss ja nie ;) ...
mov di, 0 ;nur der hier wird verändert....
mov si, mesg
mov bx,0xb800 ; Load gs to point to video memory
mov gs,bx ;diese zeile nach oben, da gs sowieso nicht mehr verändert wird...
mov ah, 6 ;6 bedeutet braun!! - eine wichtige notitz :)
next:
mov al, [si] ; si nach al
cmp al, 13 ; ist der WErt 13 ??
jne sign
mov al, [si+1] ; undn der nächste 10 ??
cmp al, 10 ; dann zeileumbruch
jne sign
inc si ;nächstes Zeichen (13)
inc si ;näcshtes zeichen (10)
mov ax, si ; si nach bx
sub ax, mesg ; si - mesg = Anzahl der ausgegebenen Zeichen
mov dx, 150 ; Bildschirmbreiet ist 150
sub dx, ax ; 150 - bx
add di,dx ; zu di dazuaddieren
mov word [gs:di],0
sign:
mov al, [si]
cmp al,0
je ende
mov word [gs:di],ax ; display
inc di ;2x inc, da wir es ja mit words zu tun haben....
inc di
inc si
jmp next
ende:
das einzige Problem daran ist, dass aus irgendwelchen Gründen die nächste Zeile sehr seltsam angezeigt wird. Was du noch beachten solltest, ist dass du di nicht mehr zurücksetzen solltest
Grüße
Morti
-
Zeilenumbruch must du zusätzlich erkennen lassen, da die Grafikkarte nicht weiss wie sie das genau behandeln soll du müsstest bei 13 dann an den anfang der zeile gehen lassen also die adresse so berechnen adr-=adr%160 weil wenn 80 zeichen pro zeile hats 160 byte hoffe das ist klar warum und für 10 einfach adr+=160 um genau eine zeile weiterzugehen.
-
Jo, das ist klar, ich wollte nur wissen obs einfacher geht. Danke für eure Hilfe jedenfalls!
-
wenn du ne Lösung hast, kannst du diese ja posten.
Grüße
Morti / FDF
-
Nein einfacher gehts echt nicht^^
-
:) Naja, da ich jetzt eh schon im PMode bin ist es auch schon egal ;)
-
Im PM bleibt aber das Prinzip das gleiche, wenn man im Textmodus bleibt;)
-
Eben deshalb wollte ich es ja wissen :) aber ich meine ich kann jetzt C verwenden was ich besser kann :)