Autor Thema: [lowlevel magazin - ausgabe 3] makros wiederholt nutzen  (Gelesen 6620 mal)

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
hallo,

ich habe folgendes problem:

ich möchte das makro, zur ausgabe von texten, aus der 3. ausgabe benutzen um mir das programmieren etwas zu erleichtern. allerdings meldet nasm dies hier:

kernel.asm: 50: error: symbol 'TextAusgabe' redefinet

das stimt auch soweit. ich gebe 2 texte nacheinander aus. oder, besser gesagt, ich will diese nacheinander ausgeben.

hier mal mein kernel:

; miniKernel Ver.s 0.1.0
;
; Aufgaben:
; * Kern des Betriebssystems
;   * Das heist:
;      + Stellt Grundlegende Funktionen und Routinen desBetriebssystems bereit
;      + Verwaltet Grundlegende Funktionen der Datenträger,
;         insbesondere das Lese,Schreiben und Ändern von Dateien und Daten
;      + Verwaltet den Speicher, Threats etc..
;
; Kernel- Typ:
; * Monolitsch
;   + Nur in der Start- bzw. Entwicklungsphase
;      Später wir der Kernel Modular Struckturiert sein....

mov ax, 0x1000 ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax ; Die Segement Register aktualisieren
mov es, ax


; Um Software Interupts nutzen zu können, müssen Hardware Interupts/ Bios Funktionen "umgeleitet" werden.
; Dafür muss eine Interrupt Vector Table erzeugt werden...:

push ax ; Inhalt speichern
push es ; Inhalt speichern
xor ax, ax ; AX Register leeren
mov es, ax ; den Inhalt von AX in ES Speichern
cli ; Hardware Interrupts ausschalten
mov word [es:0x21*4], _int0x21 ; Pointer auf den Handler zeigen lassen
mov [es:0x21*4+2], cs ; Pointer auf cs zeigen lassen
sti ; Hardware Interrupts wieder einschalten
pop es
pop ax

start:
; Anschliesend verwenden wir unseren neuen Software Interrupt, um Benutzer- Nachrichten auszugeben
mov si, msg_start ; Wir holen uns die Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

mov si,msg_boot ; Wir holen uns eine weitere Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

; Ab hier erledigt nur noch unser Software Interupt die Textausgabe
; Und: Wir benutzen Macros, welche die Arbeit erheblich erleichtern
;
; Das Makro TextAusgabe" enthält alle Anweisungen, um den Text korrekt an unser Interrupt 0x21 (mit Funktion 0x01)
; übergeben zu können
TextAusgabe db "Interrupt 21 (mit Funktion 0x01) arbeitet",13,10,0

TextAusgabe db "Druecke eine Taste, um den Computer neu zu starten...",10,0

call getkey ; Hier rufen wir nun eine Subroutine auf, die auf einem Tastendruck wartet...
jmp reboot ; Weiter gehts zu einer Subrouten, die den PC neustartet

;  Wir speichern die Nachrichten, in den nachfolgenden Variablen...:
msg_start db "Willkommen beim minOS Version 0.1.0",13,10,0
msg_boot db "Initialisiere...",13,10,0


; Es wir Zeit, die Nachrichten auszugeben...:
putstr:
lodsb ; Beginne zu lesen
or al,al
jz short putstrd ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Die Routinen und Aufrufe zum Ausgeben von Textnachrichten wurden getauscht
; Der Software Interrupt 0x21 übernimmt nun diese Aufgabe.

_int0x21: ; Unser erster eigener Interupt
 _int0x21_ser0x01: ; Die Funktion unseres Interrupts (Text ausgeben)
 cmp al, 0x01 ; wurde die Funktion wirklich aufgerufen? Dies wird hier abgefragt
 jne _int0x21_end ; wenn nein, dann weiter zur nächsten Funktion

; Nun wird es Zeit, die Funktion zu nutzen
; Dieser Software Interupt, mit der Funktion 0x01, gibt Text auf dem Bildschirm aus
 _int0x21_ser0x01_start:
 lodsb ; Jeweils ein Byte laden
 or al, al ; Zeichenkette zuende?
 jz _int0x21_ser0x01_end ; wenn ja, dann Funktion beenden. Wenn nein, dann nachfolgend weiter machen
 mov ah, 0x0E ; Bios Teletype Funktion nutzen
 mov bh, 0x00 ; Auf Page 0 schreiben
 mov bl, 0x07 ; Text Atribute
 int 0x10 ; Bios Call (Text schreiben)
 jmp _int0x21_ser0x01_start
 _int0x21_ser0x01_end:
 jmp _int0x21_end
 
 _int0x21_end:
 iret ; Software Interrupt beenden

; Makros erleichtern die Arbeit. Unter Assembler erst recht.
;Also basteln wir uns ein Makro, welcher die Ausgabe von Textnachrichten erleichtert.
%macro TextAusgabe 1
mov al, 0x01
mov si, %1
int 0x21
%endmacro
 
; Diese Funktion starte den Computer, nach einem Tastendruck, neu
getkey:
mov ah, 0 ; Prozessor Funktion 0, oder anders gesagt, Neustart, ausführen
; Dieser Aufruf bereitet den Prozessor hierfür vor
int 0x16 ; Dieser Befehl löd den Reboot Befehl aus
ret

reboot:
jmp 0xffff:0x0000 ; Alle Befehle entfernen, sowie dem Prozessor neustarten

; Das wars....
; Das ist unserer Mini- Kernel...

wie man sieht, habe ich mein kernel, siehe vorherigen beitrag( [lowlevel magazin - ausgabe 1] ... ) , erweitert.

was kann ich machen, damit ich die makros, wiederholt, nutzen kann..?

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 25. July 2008, 17:29 »
was kann ich machen, damit ich die makros, wiederholt, nutzen kann..?
Du kannst das Makro in der Form wiederholt benutzen. Du benutzt es momentan aber garnicht... Du definierst da einfach zwei Strings denen du den gleichen Namen (das TextAusgabe db blabla) gibts (warüber sich der Assembler beschwert) und das auch noch mitten im Codeteil. Also: Definier die zwei Strings im Dateinteil.
Das Makro rufst du dann über (Dazu musst du wahrscheinlich das Makro früher definieren, d.h. bevor du es benutzt)
TextAusgabe meinString
auf (im Codeteil), falls meinString eben ein String ist.Also sowas in der Richtung im Datenteil:
meinString db "I am a tool."

Ich hoffe ich konnte helfen.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 25. July 2008, 17:48 »
was kann ich machen, damit ich die makros, wiederholt, nutzen kann..?
Du kannst das Makro in der Form wiederholt benutzen. Du benutzt es momentan aber garnicht... Du definierst da einfach zwei Strings denen du den gleichen Namen (das TextAusgabe db blabla) gibts (warüber sich der Assembler beschwert) und das auch noch mitten im Codeteil. Also: Definier die zwei Strings im Dateinteil.
Das Makro rufst du dann über (Dazu musst du wahrscheinlich das Makro früher definieren, d.h. bevor du es benutzt)
TextAusgabe meinString
auf (im Codeteil), falls meinString eben ein String ist.Also sowas in der Richtung im Datenteil:
meinString db "I am a tool."

Ich hoffe ich konnte helfen.

also, wenn ich dich grad richtig verstehe, dann darf ich die zusäte ( ,13,10, 0 ) nicht verwenden...?

ich probiere das mal...

[edit] ok, das war nix...

[edit]
ich habs jetzt mal so notiert:

; miniKernel Ver.s 0.1.0
;
; Aufgaben:
; * Kern des Betriebssystems
;   * Das heist:
;      + Stellt Grundlegende Funktionen und Routinen desBetriebssystems bereit
;      + Verwaltet Grundlegende Funktionen der Datenträger,
;         insbesondere das Lese,Schreiben und Ändern von Dateien und Daten
;      + Verwaltet den Speicher, Threats etc..
;
; Kernel- Typ:
; * Monolitsch
;   + Nur in der Start- bzw. Entwicklungsphase
;      Später wir der Kernel Modular Struckturiert sein....

mov ax, 0x1000 ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax ; Die Segement Register aktualisieren
mov es, ax


; Um Software Interupts nutzen zu können, müssen Hardware Interupts/ Bios Funktionen "umgeleitet" werden.
; Dafür muss eine Interrupt Vector Table erzeugt werden...:

push ax ; Inhalt speichern
push es ; Inhalt speichern
xor ax, ax ; AX Register leeren
mov es, ax ; den Inhalt von AX in ES Speichern
cli ; Hardware Interrupts ausschalten
mov word [es:0x21*4], _int0x21 ; Pointer auf den Handler zeigen lassen
mov [es:0x21*4+2], cs ; Pointer auf cs zeigen lassen
sti ; Hardware Interrupts wieder einschalten
pop es
pop ax

start:
; Anschliesend verwenden wir unseren neuen Software Interrupt, um Benutzer- Nachrichten auszugeben
mov si, msg_start ; Wir holen uns die Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

mov si,msg_boot ; Wir holen uns eine weitere Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

; Ab hier erledigt nur noch unser Software Interupt die Textausgabe
; Und: Wir benutzen Macros, welche die Arbeit erheblich erleichtern
;
; Das Makro TextAusgabe" enthält alle Anweisungen, um den Text korrekt an unser Interrupt 0x21 (mit Funktion 0x01)
; übergeben zu können
TextAusgabe msg_interruptsLoad
textAusgabe msg_reboot

call getkey ; Hier rufen wir nun eine Subroutine auf, die auf einem Tastendruck wartet...
jmp reboot ; Weiter gehts zu einer Subrouten, die den PC neustartet

;  Wir speichern die Nachrichten, in den nachfolgenden Variablen...:
msg_start db "Willkommen beim minOS Version 0.1.0",13,10,0
msg_boot db "Initialisiere...",13,10,0
msg_interruptsLoaded db "Interrupt 21 (mit Funktion 0x01) arbeitet",13,10,0
msg_reboot db "Druecke eine Taste, um den Computer neu zu starten..."

; Es wir Zeit, die Nachrichten auszugeben...:
putstr:
lodsb ; Beginne zu lesen
or al,al
jz short putstrd ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Die Routinen und Aufrufe zum Ausgeben von Textnachrichten wurden getauscht
; Der Software Interrupt 0x21 übernimmt nun diese Aufgabe.

_int0x21: ; Unser erster eigener Interupt
 _int0x21_ser0x01: ; Die Funktion unseres Interrupts (Text ausgeben)
 cmp al, 0x01 ; wurde die Funktion wirklich aufgerufen? Dies wird hier abgefragt
 jne _int0x21_end ; wenn nein, dann weiter zur nächsten Funktion

; Nun wird es Zeit, die Funktion zu nutzen
; Dieser Software Interupt, mit der Funktion 0x01, gibt Text auf dem Bildschirm aus
 _int0x21_ser0x01_start:
 lodsb ; Jeweils ein Byte laden
 or al, al ; Zeichenkette zuende?
 jz _int0x21_ser0x01_end ; wenn ja, dann Funktion beenden. Wenn nein, dann nachfolgend weiter machen
 mov ah, 0x0E ; Bios Teletype Funktion nutzen
 mov bh, 0x00 ; Auf Page 0 schreiben
 mov bl, 0x07 ; Text Atribute
 int 0x10 ; Bios Call (Text schreiben)
 jmp _int0x21_ser0x01_start
 _int0x21_ser0x01_end:
 jmp _int0x21_end
 
 _int0x21_end:
 iret ; Software Interrupt beenden

; Makros erleichtern die Arbeit. Unter Assembler erst recht.
;Also basteln wir uns ein Makro, welcher die Ausgabe von Textnachrichten erleichtert.
%macro TextAusgabe 1
mov al, 0x01
mov si, %1
int 0x21
%endmacro
 
; Diese Funktion starte den Computer, nach einem Tastendruck, neu
getkey:
mov ah, 0 ; Prozessor Funktion 0, oder anders gesagt, Neustart, ausführen
; Dieser Aufruf bereitet den Prozessor hierfür vor
int 0x16 ; Dieser Befehl löd den Reboot Befehl aus
ret

reboot:
jmp 0xffff:0x0000 ; Alle Befehle entfernen, sowie dem Prozessor neustarten

; Das wars....
; Das ist unserer Mini- Kernel...

nasm meldet: kernel.asm: 48: error: instruction expected
ich denke, da fehlt noch ein befehl.... mal sehen, was ich da machen kann...

[edit] tipp fehler bei msg_interruptsLoad.. gefixt
« Letzte Änderung: 25. July 2008, 17:58 von Gamepower »

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 25. July 2008, 18:16 »
soo... ich habe den kernel, wie folgt, verändert:

; miniKernel Ver.s 0.1.0
;
; Aufgaben:
; * Kern des Betriebssystems
;   * Das heist:
;      + Stellt Grundlegende Funktionen und Routinen desBetriebssystems bereit
;      + Verwaltet Grundlegende Funktionen der Datenträger,
;         insbesondere das Lese,Schreiben und Ändern von Dateien und Daten
;      + Verwaltet den Speicher, Threats etc..
;
; Kernel- Typ:
; * Monolitsch
;   + Nur in der Start- bzw. Entwicklungsphase
;      Später wir der Kernel Modular Struckturiert sein....

mov ax, 0x1000 ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax ; Die Segement Register aktualisieren
mov es, ax


; Um Software Interupts nutzen zu können, müssen Hardware Interupts/ Bios Funktionen "umgeleitet" werden.
; Dafür muss eine Interrupt Vector Table erzeugt werden...:

push ax ; Inhalt speichern
push es ; Inhalt speichern
xor ax, ax ; AX Register leeren
mov es, ax ; den Inhalt von AX in ES Speichern
cli ; Hardware Interrupts ausschalten
mov word [es:0x21*4], _int0x21 ; Pointer auf den Handler zeigen lassen
mov [es:0x21*4+2], cs ; Pointer auf cs zeigen lassen
sti ; Hardware Interrupts wieder einschalten
pop es
pop ax

start:
; Anschliesend verwenden wir unseren neuen Software Interrupt, um Benutzer- Nachrichten auszugeben
mov si, msg_start ; Wir holen uns die Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

mov si,msg_boot ; Wir holen uns eine weitere Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

; Makros erleichtern die Arbeit. Unter Assembler erst recht.
;Also basteln wir uns ein Makro, welcher die Ausgabe von Textnachrichten erleichtert.
%macro TextAusgabe 1
mov al, 0x01
mov si, %1
int 0x21
%endmacro

call getkey ; Hier rufen wir nun eine Subroutine auf, die auf einem Tastendruck wartet...
jmp reboot ; Weiter gehts zu einer Subrouten, die den PC neustartet




;  Wir speichern die Nachrichten, in den nachfolgenden Variablen...:
msg_start db "Willkommen beim minOS Version 0.1.0",13,10,0
msg_boot db "Initialisiere...",13,10,0

; Ab hier erledigt nur noch unser Software Interupt die Textausgabe
; Und: Wir benutzen Macros, welche die Arbeit erheblich erleichtern
;
msg_interruptsLoaded db "Interrupt 21 (mit Funktion 0x01) arbeitet",13,10,0
msg_reboot db "Druecke eine Taste, um den Computer neu zu starten...",13,10,0
; Das Makro TextAusgabe" enthält alle Anweisungen, um den Text korrekt an unser Interrupt 0x21 (mit Funktion 0x01)
; übergeben zu können
TextAusgabe msg_interruptsLoaded
TextAusgabe msg_reboot

; Es wir Zeit, die Nachrichten auszugeben...:
putstr:
lodsb ; Beginne zu lesen
or al,al
jz short putstrd ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Die Routinen und Aufrufe zum Ausgeben von Textnachrichten wurden getauscht
; Der Software Interrupt 0x21 übernimmt nun diese Aufgabe.

_int0x21: ; Unser erster eigener Interupt
 _int0x21_ser0x01: ; Die Funktion unseres Interrupts (Text ausgeben)
 cmp al, 0x01 ; wurde die Funktion wirklich aufgerufen? Dies wird hier abgefragt
 jne _int0x21_end ; wenn nein, dann weiter zur nächsten Funktion

; Nun wird es Zeit, die Funktion zu nutzen
; Dieser Software Interupt, mit der Funktion 0x01, gibt Text auf dem Bildschirm aus
 _int0x21_ser0x01_start:
 lodsb ; Jeweils ein Byte laden
 or al, al ; Zeichenkette zuende?
 jz _int0x21_ser0x01_end ; wenn ja, dann Funktion beenden. Wenn nein, dann nachfolgend weiter machen
 mov ah, 0x0E ; Bios Teletype Funktion nutzen
 mov bh, 0x00 ; Auf Page 0 schreiben
 mov bl, 0x07 ; Text Atribute
 int 0x10 ; Bios Call (Text schreiben)
 jmp _int0x21_ser0x01_start
 _int0x21_ser0x01_end:
 jmp _int0x21_end
 
 _int0x21_end:
 iret ; Software Interrupt beenden

 
; Diese Funktion starte den Computer, nach einem Tastendruck, neu
getkey:
mov ah, 0 ; Prozessor Funktion 0, oder anders gesagt, Neustart, ausführen
; Dieser Aufruf bereitet den Prozessor hierfür vor
int 0x16 ; Dieser Befehl löd den Reboot Befehl aus
ret

reboot:
jmp 0xffff:0x0000 ; Alle Befehle entfernen, sowie dem Prozessor neustarten

; Das wars....
; Das ist unserer Mini- Kernel...

nasm kompiliert das ganze anstandslos. allerdings sehe ich die 2 textzeilen, als output, nicht mehr... schreibe ich in den falschen speicherbereich, oder wo liegt das problem...?

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 25. July 2008, 18:33 »
problem gelöst... mein kernel sieht nun so aus:

; miniKernel Ver.s 0.1.0
;
; Aufgaben:
; * Kern des Betriebssystems
;   * Das heist:
;      + Stellt Grundlegende Funktionen und Routinen desBetriebssystems bereit
;      + Verwaltet Grundlegende Funktionen der Datenträger,
;         insbesondere das Lese,Schreiben und Ändern von Dateien und Daten
;      + Verwaltet den Speicher, Threats etc..
;
; Kernel- Typ:
; * Monolitsch
;   + Nur in der Start- bzw. Entwicklungsphase
;      Später wir der Kernel Modular Struckturiert sein....

mov ax, 0x1000 ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax ; Die Segement Register aktualisieren
mov es, ax


; Um Software Interupts nutzen zu können, müssen Hardware Interupts/ Bios Funktionen "umgeleitet" werden.
; Dafür muss eine Interrupt Vector Table erzeugt werden...:

push ax ; Inhalt speichern
push es ; Inhalt speichern
xor ax, ax ; AX Register leeren
mov es, ax ; den Inhalt von AX in ES Speichern
cli ; Hardware Interrupts ausschalten
mov word [es:0x21*4], _int0x21 ; Pointer auf den Handler zeigen lassen
mov [es:0x21*4+2], cs ; Pointer auf cs zeigen lassen
sti ; Hardware Interrupts wieder einschalten
pop es
pop ax

; Makros erleichtern die Arbeit. Unter Assembler erst recht.
;Also basteln wir uns ein Makro, welcher die Ausgabe von Textnachrichten erleichtert.
%macro TextAusgabe 1
mov al, 0x01
mov si, %1
int 0x21
%endmacro

start:
; Anschliesend verwenden wir unseren neuen Software Interrupt, um Benutzer- Nachrichten auszugeben
mov si, msg_start ; Wir holen uns die Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

mov si,msg_boot ; Wir holen uns eine weitere Adresse der Nachricht
call putstr ; Und leiten das ganze an die "Textausgabe" weiter

; Ab hier erledigt nur noch unser Software Interupt die Textausgabe
; Und: Wir benutzen Macros, welche die Arbeit erheblich erleichtern
TextAusgabe msg_interruptsLoaded
TextAusgabe msg_reboot

call getkey ; Hier rufen wir nun eine Subroutine auf, die auf einem Tastendruck wartet...
jmp reboot ; Weiter gehts zu einer Subrouten, die den PC neustartet

;  Wir speichern die Nachrichten, in den nachfolgenden Variablen...:
msg_start db "Willkommen beim minOS Version 0.1.0",13,10,0
msg_boot db "Initialisiere...",13,10,0

; Texte, die unser Makro benutzt
msg_interruptsLoaded db "Interrupt 21 (mit Funktion 0x01) arbeitet",13,10,0
msg_reboot db "Druecke eine Taste, um den Computer neu zu starten...",13,10,0
; Das Makro TextAusgabe" enthält alle Anweisungen, um den Text korrekt an unser Interrupt 0x21 (mit Funktion 0x01)
; übergeben zu können

; Nachrichten, ohne Software Interrupts ausgeben...
; "Klassische" Methode, die die Bios Funktionen benutzt
putstr:
lodsb ; Beginne zu lesen
or al,al
jz short putstrd ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Die Routinen und Aufrufe zum Ausgeben von Textnachrichten wurden getauscht
; Der Software Interrupt 0x21 übernimmt nun diese Aufgabe.

_int0x21: ; Unser erster eigener Interupt
 _int0x21_ser0x01: ; Die Funktion unseres Interrupts (Text ausgeben)
 cmp al, 0x01 ; wurde die Funktion wirklich aufgerufen? Dies wird hier abgefragt
 jne _int0x21_end ; wenn nein, dann weiter zur nächsten Funktion

; Nun wird es Zeit, die Funktion zu nutzen
; Dieser Software Interupt, mit der Funktion 0x01, gibt Text auf dem Bildschirm aus
 _int0x21_ser0x01_start:
 lodsb ; Jeweils ein Byte laden
 or al, al ; Zeichenkette zuende?
 jz _int0x21_ser0x01_end ; wenn ja, dann Funktion beenden. Wenn nein, dann nachfolgend weiter machen
 mov ah, 0x0E ; Bios Teletype Funktion nutzen
 mov bh, 0x00 ; Auf Page 0 schreiben
 mov bl, 0x07 ; Text Atribute
 int 0x10 ; Bios Call (Text schreiben)
 jmp _int0x21_ser0x01_start
 _int0x21_ser0x01_end:
 jmp _int0x21_end
 
 _int0x21_end:
 iret ; Software Interrupt beenden

 
; Diese Funktion starte den Computer, nach einem Tastendruck, neu
getkey:
mov ah, 0 ; Prozessor Funktion 0, oder anders gesagt, Neustart, ausführen
; Dieser Aufruf bereitet den Prozessor hierfür vor
int 0x16 ; Dieser Befehl löd den Reboot Befehl aus
ret

reboot:
jmp 0xffff:0x0000 ; Alle Befehle entfernen, sowie dem Prozessor neustarten

; Das wars....
; Das ist unserer Mini- Kernel...

auch diesem code können zukünftige os dev´s nutzen :)

[edit]

stimmen meine, für mich gedachten, erklärungen in den kommentaren?

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 25. July 2008, 19:03 »
Zitat
mov ax, 0x1000              ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax                      ; Die Segement Register aktualisieren
mov es, ax
Du "positionierst" damit nicht den Kernel und schon garnicht an Adresse 0x1000. Schau dir die Adressierung über Segment:Offset im Realmode nochmal genauer an. In dem Fall wäre es wenn überhaupt Adresse 0x10000, wobei du da nichts "positionierst", sondern einfach die Segmentregister setzt, damit du bei Speicherzugriffen auf die richtige Stelle zugreifst.

edit: Vielleicht sag ich da doch noch dazu :-) : Sobald du mit einem mov auf den Speicher zugreifst, wird implizit (zumindest meisten, die Ausnahmen führen hier allerdings zu weit, aber es wird implizit immer eines der Segmentregister hergenommen) ds als Segmentregister hergenommen. Also Beispiel:
mov ax, [somestuff]
Dann wird das Word an der Adress ds:somestuff (physikalisch dann ds * 16 + somestuff) ausgelesen. Deswegen ist es so wichtig die Segmentregister richtig zu setzen, sondern schreibst/liest/führst aus irgendeinen Mist im Speicher.

Zitat
also, wenn ich dich grad richtig verstehe, dann darf ich die zusäte ( ,13,10, 0 ) nicht verwenden...?
Das ist natürlich Blödsinn, du brauchst das 13 und 10 um in eine neue Zeile zu kommen und das 0 um das Ende der Zeichenkette zu erkennen. Ich hab das nur aus Unachtsamkeit vergessen.
« Letzte Änderung: 25. July 2008, 19:06 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 25. July 2008, 19:15 »
Zitat
mov ax, 0x1000              ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax                      ; Die Segement Register aktualisieren
mov es, ax
Du "positionierst" damit nicht den Kernel und schon garnicht an Adresse 0x1000. Schau dir die Adressierung über Segment:Offset im Realmode nochmal genauer an. In dem Fall wäre es wenn überhaupt Adresse 0x10000, wobei du da nichts "positionierst", sondern einfach die Segmentregister setzt, damit du bei Speicherzugriffen auf die richtige Stelle zugreifst.

edit: Vielleicht sag ich da doch noch dazu :-) : Sobald du mit einem mov auf den Speicher zugreifst, wird implizit (zumindest meisten, die Ausnahmen führen hier allerdings zu weit, aber es wird implizit immer eines der Segmentregister hergenommen) ds als Segmentregister hergenommen. Also Beispiel:
mov ax, [somestuff]
Dann wird das Word an der Adress ds:somestuff (physikalisch dann ds * 16 + somestuff) ausgelesen. Deswegen ist es so wichtig die Segmentregister richtig zu setzen, sondern schreibst/liest/führst aus irgendeinen Mist im Speicher.

Zitat
also, wenn ich dich grad richtig verstehe, dann darf ich die zusäte ( ,13,10, 0 ) nicht verwenden...?
Das ist natürlich Blödsinn, du brauchst das 13 und 10 um in eine neue Zeile zu kommen und das 0 um das Ende der Zeichenkette zu erkennen. Ich hab das nur aus Unachtsamkeit vergessen.

macht nix. meine strings werden nun korrekt ausgegeben. siehe kopie des kernel quelltextes über dir. die angabe der tabellen (13,10,0) habe ich den rohstring angehängt, was auch ohne problem funktioniert.

alles andere..: das muss ich noch korrigieren. das ganze ist eine, etwas, ältere kopie des quelltextes...

 

Einloggen