Lowlevel

OffZone => Offtopic => Thema gestartet von: Dimension am 09. January 2012, 16:39

Titel: ExportStructure..java
Beitrag von: Dimension am 09. January 2012, 16:39
Ich brauche eine Rückmeldung zum Code, welcher den Zugriff auf x86-Srukturen konvertiert. Ich hoffe jmd hier kann Java lesen. Das ginge zwar mit C wesentlich einfacher, aber ich bin halt schon sehr weit mit dem Import für Java. Der Code hat ein Indent von 4 Zeichen und wird von Pastebin nicht korrekt dargestellt.

http://pastebin.com/gXMVMhB7

Kann da mal jemand drüber schauen? Sind alle Bits, Offsets, Byte-Orders und Flags korrekt? Der Code besteht aus 6 Klassen:
- InterruptDescriptorTablleRegister
- InterruptDescriptor
- GlobalDescriptorTableRegister (äquivalent zu Local)
- GlobalDescriptor (äquivalent zu Local)
- PageDirektoryEntry (äquivalent zu PageTableEntry)
- TaskSegmentDescriptor, unfertig

Jede Klasse beinhaltet die Methoden read und write, sowie einen Feldselektor "Field", welcher das Feld auswählt. Einige Klassen beinhalten zusätzlich Unterklassen für Flags und komprimierte Werte. Die Methode read gibt entweder einen 32-Bit Integerwert oder ein Objekt einer der Unterklassen zurück. Die Methode write nimmt ein solches Objekt entgegen und schreibt es in "structure".

Der Parameter "int start" ist überflüssig.

Ich beschäfte mich gerade mit dem Bootloader (GRUB). Nach 4 Stunden (und einem Haufen anstrengender Fehlermeldungen) habe ich erfolgreiches Plattenimage für Bochs kreiert.
Titel: Re: ExportStructure..java
Beitrag von: kevin am 09. January 2012, 17:09
Urgs, das ist ja gruselig. :)

Auf den ersten Blick ist mir nichts falsches aufgefallen, wobei ich das ganze Zeug auch nicht auswendig weiß. Ich würde an deiner Stelle ein paar Testfälle schreiben, die einige Kombinationen ausgeben lassen und von denen der richtige Wert leicht in einem Emulator überprüft werden kann.
Titel: Re: ExportStructure..java
Beitrag von: Dimension am 05. February 2012, 13:30
Hinsichtlich der simulerten Schreib/Leseoperationen auf ein byte[] in Java habe ich festgestellt, dass man noch einigen zusätzlichen Aufwand betreiben muss, um korrekte unsigned 16/32-Bit-Werte aus dem Speicher zu lesen oder dorthin zu schreiben. Zuerst muss man beachten, dass Java nur signed 16/32-Bit-Werte bereitstellt. Auch wenn das höchte Bit weiterhin verfügbar ist, muss, um korrekt rechnen zu können, jeweils der nächstgrößere Datentyp verwendet werden. Bei den Konvertierungen der 8-Bit-Werte aus dem Array muss zuerst in den Zieltyp gecastet und mit 0xFF maskiert werden, bevor die Werte geshiftet und zum Resultat kombiniert werden. In der umgekehrten Richtung reicht allerdings ein Shift und ein Cast, wahlweise mit Maskierung vor oder nach dem Shift.

Bei den auftretenden Casts habe ich folgendes Verhalten beobachten können:
(byte) 0x7F -> (short) 0x007F // wird mit Nullen aufgefüllt
(byte) 0x80 -> (short) 0xFF80 // wird mit Einsen aufgefüllt
(short) 0x007F -> (byte) 0x7F
(short) 0x0080 -> (byte) 0x80 // Vorzeichenwechsel
(short) 0xFF80 -> (byte) 0x80
(short) 0xFF7F -> (byte) 0x7F // Vorzeichenwechsel
Während das Verhalten der ersten beiden Erwartungsgemäß ist, kam mir das Verhalten des 4. und 6. Casts etwas merkwürdig vor.
Bei einem Cast in einen größeren Datentyp werden die oberen Bytes mit dem höchsten Bit (=Vorzeichenbit) des Ausgangswerts aufgefüllt. Bei einem Cast in einen kleineren Datentyp werden die oberen Bytes einfach abgeschnitten, das höchste Bit des Resultats bleibt unverändert. Hier findet also bei jeder negativen Zahl ein Overflow und möglicherweise auch ein Vorzeichenwechsel statt.
Auf den 2. Blick ist dieses Verhalten allerdings nachvollziehbar, da korrekt gecastet wird, falls der (negative) Ausgangswert in den Datentyp des Resultats passt. In diesem Fall ist das höchste Bit des Resultats im Zweierkomplement bereits korrekt gesetzt