PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Textmodus-Bildschirmspeicher auslesen


aths
2007-08-11, 13:31:06
Ich will (mit TASM) unter DOS beim normalen 80x25-16-Farb-Textmodus die Hintergrundfarbe eines Zeichens an einer bestimmten Stelle (sagen wir zehnte Zeile, zehnte Spalte) wissen. Dann will ich diese Farbe als Errorlevel beim Beenden an DOS übergeben. Dazu benötige ich eine Reihe an Informationen:

- Wie genau ist der Bildschirmspeicher aufgebaut? Ich glaube er beginnt bei B800 und nutzt pro Zeichen zwei Byte (ASCII-Code, Attribut) – wie ist im Attribut die Hintergrundfarbe kodiert?

- Wie greife ich in Assembler auf eine bestimmte Speicherposition zu? (Hier eben B800:XXXX)

- Wie setze ich vor dem mov ah, 4ch – int 21h das Errorlevel?

KhanRKerensky
2007-08-11, 14:47:30
- Wie greife ich in Assembler auf eine bestimmte Speicherposition zu? (Hier eben B800:XXXX)
Das geht über die Segmentregister. Die kann man aber glaube ich nicht direkt mit Werten belegen. Da musst du derartiges machen:
mov ax, b800
mov es, ax
Und dann kannst du [es:bx] als Farpointer verwenden.

- Wie setze ich vor dem mov ah, 4ch – int 21h das Errorlevel?
Schieb deinen Wert einfach in al.

http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte1at0.htm
Prinzipiell würd ich mir allerdings erstmal den BIOS Interrupt 10h anschauen.
Mit ah = 02h kann man den Cursor setzten und mit ah = 08h kann man das Zeichen mitsammt Attribut auslesen. Interrupts dürften zwar langsamer als das direkte Auslesen sein, aber das ist deutlich einfacher.

aths
2007-08-11, 14:59:19
Das geht über die Segmentregister. Die kann man aber glaube ich nicht direkt mit Werten belegen. Da musst du derartiges machen:
mov ax, b800
mov es, ax
Und dann kannst du [es:bx] als Farpointer verwenden.Also folgendermaßen?

.MODEL small
.STACK 100h
mov ax, b800h
mov es, ax
mov bx, 655h ; Dezimal 1621, nämlich 2x (10 x 80 + 10) +1
mov al, [es:bx]

und dann ist das Attribut-Byte in AL, so dass ich gleich zurück ins DOS kann?

mov ah,4ch
int 21h
END


Wobei ich eben nicht weiß, wie das Attribut-Byte kodiert ist. Jeweils 4 Bit für Vorder- und Hintergrundfarbe? In welcher Reihenfolge? Ich müsste AL noch entsprechend mit AND maskieren, um nur die Hintergrundfarbe zu bekommen.

Interrupts dürften zwar langsamer als das direkte Auslesen sein, aber das ist deutlich einfacher.Das Programm würde über die Interrupt-Lösung doch deutlich länger, oder nicht?

KhanRKerensky
2007-08-11, 22:26:57
Ich hab zwar noch nie mit einem Assembler mit Intel-Syntax gearbeitet, aber das sieht eigentlich ganz gut aus.

Ich hab grad mal hier (http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_23/CH23-1.html#HEADING1-15) nachgesehen und demnach müsstest du noch ein
and al, 70h
(shr al, 4)
mit einschieben damit du nur die Hintergrundfarbe hast.

Mit den Interrupts wäre es zwar etwas länger (ich bezweifel allerdings das man das in der Ausführung merken könnte), aber auch leserlicher. Zeile, Spalte und auch die Page ließen sich leichter ändern.
Mit Interrupts (und NASM Syntax) sähe es so aus (getestet in der DOSBox):
org 100h
mov ah, 02h ; Cursorposition
mov bh, 00h ; Bildschirmseite
mov dh, 10 ; Zeile und
mov dl, 10 ; Spalte (beides ließe sich auch gleichzeitig mit mov dx, 0a0ah setzten lassen
int 10h ; Interrupt für Videooperationen
mov ah, 08h ; Zeichen lesen.
int 10h
shr ax, 12 ; Hintergrundfarbe ans LSB von ax schieben
and al, 07h ; Das Blinkbit wegmaskieren
mov ah, 4ch ; Zurück zu Dos
int 21h

Wobei ich mich grad frag wozu du das brauchst... Die Hintergrundfarbe eines bestimmten Buchstabens an Dos zurückgeben erscheint nicht gerade sinnvoll.

aths
2007-08-12, 00:43:27
Der Link dort hat geholfen. Danke. Testen kann ich es erst irgendwann nächste Woche.