Bitfelder sind nie eine gute Idee, wenn du eine bestimmte Anordnung brauchst, weil die Anordnung schlicht undefiniert ist.
Hm. Ich weiß, dass Bitfelder für Registerbeschreibungen eingesetzt werden, weil es den Code lesbar halten kann und einem das manuelle Ausmaskieren (und damit Fehler) erspart. Ist natürlich alles implementation-defined, aber das wäre hier ja eher egal. In C++ kann man Bitfelder auch portabel als Klasse nachbilden und bekommt dann typsichere Registerbeschreibungen.
Im von dir verlinkten Tutorial finde ich aber nur dass die Funktionen set_entry und load_gdt aufgerufen werden, aber die sind nirgendwo definiert, oder zu mindest habe ich die nicht gefunden.
Den Code dazu findest du im
Artikel zur GDT.
Von welchem Bitfeld redest du? Die gdt_entry struct? Und wenn ja, was bringen mir da unions? Ich weiss eigentlich schon wie unions funktionieren, ich seh nur den Anwendungszweck in dem Zusammenhang gerade nicht.
Das ist ein sehr breiter Weg ins Land von implementation-defined und daher nur vorsichtig zu genießen (ungetestet):
union gdt_entry {
struct {
unsigned limit_low : 16;
unsigned base_low : 24;
unsigned type : 4;
unsigned segment : 1;
unsigned dpl : 1;
unsigned present : 1;
unsigned limit_high : 4;
unsigned available : 1;
unsigned longmode : 1;
unsigned size : 1;
unsigned granularity : 1;
unsigned base_high : 8;
} PACKED;
char raw[8];
};
Damit kannst du jedes Teilfeld des Registers einzeln setzen und lesen, wobei der Compiler das Maskieren und Shiften für dich erledigt; das gesamte Register findest du dann, wenn du "raw" ausliest.
Achtung: Bitfelder sind pfui. In ein Element einer Union was reinschreiben und aus einem anderen Element etwas rauslesen ist auch pfui. Da musst du aufpassen, was dein Compiler draus macht.
Gruß,
Svenska