Autor Thema: BIOS Data Area auf capslock überprüfen  (Gelesen 6001 mal)

Keks

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« am: 28. January 2013, 09:41 »
Servus liebe Leute, ich bin neu hier und bin grade dabei ein bisschen mit eigenen Bootloadern zu experimentieren.

Naja bis jetzt hab einen Bootloader geschrieben mit dem ich über die Bios interrupts in den Grafik Modus wechsel und dann anschließend Pixel für Pixel den Kompletten Bildschirmbereich abfahre und sobald eine seite fertig ist kommt die nächste in einer neuen Farbe.
Gut, das hat alles geklappt nur jetzt wollte ich mal die Bios data area "auslesen" an dem Offset 0x97 dazu hab ich folgenden Quelltext in vielen verschiedenen Varianten ausprobiert:

[BITS 16]


start:
CALL Print
JMP start

Print:

MOV AH, 0x00
INT 0x16

MOV BX, [0x0497]
MOV AL, BH

AND AL, 0x04
SHR AL, 0x03
ADD AL, 0x30

MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x0F

INT 0x10



RET


TIMES 510 - ($ - $$) db 0
dw 0xAA55


Ziel war es nicht zu überprüfen ob das Capslock aktiviert ist oder nicht. Das könnte ich schließlich auch mit einem BIOS interrupt überprüfen. Ich wollte eigenlich nur gucken ob es mir gelingt zugriff auf diese Speicherstelle zu bekommen. Leider blicke ich da nicht richtig durch.
Wäre schön wenn mir jemand erklären könnte was hier schief gelaufen ist.

P.S. : Ein großes Lob an alle die an dieser Seite Mitwirken, hier gibt es echt viele nützliche informationen. Besonders gefällt mir das Magazin.
Ich verwende den NASM und lasse den Bootloader auf einem etwas älteren Laptop laufen.
Danke auch für die Literaturempfehlungen, habe mir jetzt das Buch von Reiner Backer bestellt.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 28. January 2013, 16:44 »
Hallo und willkommen and Board.

Da du keine Fehlerbeschreibung geliefert hast, vermute ich mal, dass das Problem ist, dass Caps Lock nicht erkannt wird.

Du solltest das Segmentregister, über das du auf das BIOS zugreifst, auf 0 setzen. Niemand garantiert dir, dass das beim Sprung in den Bootloader dieses den Wert 0 hat. (Wenn du einfach CS und DS dauerhaft auf 0 setzt, solltest du das org 0x7c00 am Anfang nicht vergessen.)

Ich glaube das eigentliche Problem ist, dass du das falsche Flag ausliest. Falls unserem Wiki in dieser Angelegenheit zu trauen ist, ist es Bit 6 nicht 2, das das Flag enthält. Du shiftest übrigens auch eins zu weit.

AND AL, 0x80
SHR AL, 7

Edit: Ich hab mich verguckt. In der BDA gibt es mehrere Tastaturflags ...

Btw: Wenn du Code in den Posts hast, kannst du [code] statt [b] verwenden.
« Letzte Änderung: 28. January 2013, 20:47 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

Keks

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 28. January 2013, 20:25 »
Problem gelöst :)
Herzlichen dank für deine Hilfe, du hattest recht wegen der Segmentadresse.

Habe den Code geändert in :

[BITS 16]
ORG 0x7C00


MOV AX, 0x00000000
MOV [0x7F00], AX
LDS SI, [0x7F00]


start:
CALL Print
JMP start

Print:

MOV AH, 0x00
INT 0x16

MOV BX, [0x0497]
MOV AL, BL

AND AL, 0x04
SHR AL, 0x02
ADD AL, 0x30

MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x0F

INT 0x10



RET


TIMES 510 - ($ - $$) db 0
dw 0xAA55

Und jetzt erhalte ich immer wenn ich auf das Capslock drücke eine 1.
Ich muss auf jeden fall noch viel lernen. Das mit der Adressierung ist für mich ziehmlich Kompliziert.
Mein Problem war es, dass ich dachte mit dem Befehl " MOV AX, [0x0497] " gebe ich direkt die Physikalische adresse an, dabei ist es nur die Offset Adresse.
« Letzte Änderung: 28. January 2013, 20:29 von Keks »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 28. January 2013, 20:39 »
Deine Methode die Segmentregister zu laden ist etwas seltsam und funktioniert so wie du das hast nur zufällig. LDS lädt DS und das angegebene Register SI gleichzeitig und liest 2 words. Du schreibst an die Stelle 0x7f00 aber nur eins (AX ist 1 word groß). Du müsstest auch noch an 0x7f02 eine 0 schreiben (oder EAX nutzen). Allerdings kannst du DS auch über ein Register laden, was in diesem Fall eleganter ist:

MOV AX, 0
MOV DS, AX
Dieser Text wird unter jedem Beitrag angezeigt.

Keks

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 29. January 2013, 02:50 »
Nochmals tausend dank für deine Antwort  :-D  mir ist eben auch ein Licht aufgegangen. Im Datensegmentregister ist (wie der name es eigentlich schon sagen sollte) die Segmentadresse gespeichert, die benutzt wird um auf Daten zuzugreifen. Kann man das so Sagen?
Ich hab diese eigenartige Methode auch nur benutzt, weil in dem Wikipedia Buch "Assembler Programmierung für x86 Prozessoren" drin steht, dass man die Adressregister nicht direkt verändern kann.
Jedenfalls funktioniert es jetzt und ich bin glücklich und zufrieden^^

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 29. January 2013, 09:42 »
Im Datensegmentregister ist (wie der name es eigentlich schon sagen sollte) die Segmentadresse gespeichert, die benutzt wird um auf Daten zuzugreifen. Kann man das so Sagen?
Ja, so in etwa. DS wird automatisch für alle Daten Zugriffe verwendet. SS für alle Zugriffe mit Hilfe von SP oder BP und CS für den Code. Wie sich die tatsächliche Adresse dann zu sammen setzt kannst du hier nachlesen „Real Mode Speicheradressierung“

Ich hab diese eigenartige Methode auch nur benutzt, weil in dem Wikipedia Buch "Assembler Programmierung für x86 Prozessoren" drin steht, dass man die Adressregister nicht direkt verändern kann.
Damit ist gemeint das ein "mov ds, 0" nicht funktioniert.

Zitat
Jedenfalls funktioniert es jetzt
Das ist leider noch ein wenig Zufällig, weil du nicht nur beim DatenSegment nicht weißt welcher Wert drin steht. Du solltest auch das CS mit einem Wert initialisieren.
[org 0x7C00]
jmp 0x00:jetzt_ist_CS_null
jetzt_ist_CS_null:

// DS null setzen, und loslegen


„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Keks

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 30. January 2013, 07:41 »
Auch dir sei herzlich gedankt, MNemo.
Die Speicheradressierung scheint ein ziehmlich komplexes Thema zu sein, auf dem Link kann ich zwar entnehmen wie die sie die Physikalische Adresse aus Segment und Offset zusammensetzt, welche konkreten Register verwendet leider nicht.
Jetzt verstehe ich nur nicht so ganz wieso ich noch das CS mit 0 initialisieren sollte, wird das auch noch mit verwendet bei der Adressberechnung für die Adresse die ich auslesen will?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 30. January 2013, 09:14 »
Jetzt verstehe ich nur nicht so ganz wieso ich noch das CS mit 0 initialisieren sollte, wird das auch noch mit verwendet bei der Adressberechnung für die Adresse die ich auslesen will?
Es wird für den Code gebraucht. Also ein CALL Print ist z. B. ein CALL CS:Print. Und wenn sich der BIOS Hersteller gedacht hat, es ist toller wenn der Bootsektor bei Segment Offset 0 anfängt dann Startet dein Code bei 0x07C0:0x0000 = 0x7C00, wegen ORG 0x7C00 ist dein Print-lable aber 0x7C00 + X und du würdest mit 0x07C0:0x7C00 + X = 0xF800 + X nicht mehr bei deinem Code landen.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Keks

  • Beiträge: 5
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 30. January 2013, 22:44 »
Ok habs jetzt verstanden :) Danke dir.
« Letzte Änderung: 30. January 2013, 23:01 von Keks »

 

Einloggen