Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: RedEagle am 29. December 2005, 09:48

Titel: Problem mit inlineassambler und lidt
Beitrag von: RedEagle am 29. December 2005, 09:48
Mein code:
INTERRUPT idt[256];
DWORD     ptr_idtr[3];

bool LoadIDT()
{
 ptr_idtr[0] = (sizeof(INTERRUPT)*256) << 16;
 ptr_idtr[1] = (DWORD)idt;
 
 __asm__ __volatile__ ("LIDT (%0) ": :"p" (&ptr_idtr[3]) );

 return true;
}


Bei dem asm-teil gibts ein Linkererror:
\idt.obj(.text+0x4e):idt.cpp: undefined reference to '$_ptr_idtr'
\idt.obj(.text+0x260):idt.cpp: undefined reference to '$_ptr_idtr'


Wenn ich den asm-teil rauskommentiere gibt's keine Probleme...

Wo ist mein Fehler??
Titel: Problem mit inlineassambler und lidt
Beitrag von: Jidder am 29. December 2005, 12:10
Hi,

das Problem ist, dass ptr_idtr global ist. Wenn GCC den Assemblercode erzeugt landet der Datenteil (also die globalen Variablen) unter dem Code-Teil und sind damit anscheinend für den Assembler nicht sichtbar. Die einfachste Lösung ist ptr_idtr in den scope der Funktion zu setzen.

Außerdem glaube ich dass &ptr_idtr[3] falsch ist. Sollte das vielleicht (char*)ptr_idtr + 2 heissen? ;) Ich würde sowieso ein struct für die idtr empfehlen und nicht mit irgendwelchen Arrays rumfummeln. Das << 16 und &ptr_idtr[3] (bzw. (char*)ptr_idtr + 2) sind ja schon genug Argumente dagegen.

PorkChicken
Titel: Problem mit inlineassambler und lidt
Beitrag von: RedEagle am 21. January 2006, 20:52
sry für die Späte antwort, hatte aber in letzter Zeit andere Probleme...

Ich habe jetzt ein sturct genommen:

typedef struct
{
 WORD       limit;
 INTERRUPT *base;
} __attribute__ ((packed)) IDTR;


IDTR idtr;

//-----------------------------------------------------------------------------------

bool LoadIDT()
{
// static IDTR idtr;
 idtr.limit = (sizeof(INTERRUPT)*256)-1;
 idtr.base  = idt;

 IDTR *pidtr = &idtr;
 asm volatile ("LIDT (%0) ": :"p" (pidtr)); //undefined reference to $_idtr

 return true;
}


immernoch undefined reference...
Wenn ich idtr lokal mache (wie hier wegkommentiert ist) lässt es sich zwar kompilieren, habe aber die Selbe reaktion als wenn ich es Global mache, und den asm-teil weglasse (beides verursacht einen reboot)

Ich bin langsam am verzweifeln.

Ich habe mir mal den Code von "Pirat" angesehen, (wie man an meinem code evtl sieht ;) ) und da scheint es so zu funktionieren... warum aber bei mir nicht ??
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: RedEagle am 05. September 2007, 14:37
Der Beitrag ist zwar schon alt, aber:...

Ich überarbeite meinen kernel momentan, und dabei kam es erneut zu dem oben genannten Problem.

Da noch keine Lösung gepostet wurde, und evtl andere leute selbiges Problem haben/bekommen, möchte ich die Lösung des Problems posten.

Das Problem liegt an der inline-assembler-zeile.
Die muss wie folgt lauten:

asm volatile ("LIDT (%%eax) ": :"p" (pidtr));
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: middle_endian am 05. September 2007, 17:44
welche gcc version verwendest du?
ich bekomm einen internal-compiler error.
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: RedEagle am 05. September 2007, 18:22
gcc 4.1.0
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: MNemo am 06. September 2007, 15:53
also mit gcc 4.1.3
würde die Zeile
asm volatile ("LIDT (%%eax) ": :"p" (pidtr));zu einem Fehler führen(der wegen compiler optimierungen möglicher weise erst nach anderen änderungen 'sichtbar' wird), weil eax nicht mit pidtr initialiesiert wird.

Deshalb würde ich es folgender maßen machen.
asm volatile ("LIDT (%0) " : : "r" (pidtr)); das funktioniert auf jeden fall, weil zu erst ein register 'x' mit pidtr geladen wird und dann dann mit 'lidt ' benutzt wird.
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: middle_endian am 06. September 2007, 21:40
@MNemo: das hab ich auch versucht, allerdings gibts da auch einen internal compiler-error.
idt.cpp:57: internal compiler error: in emit_move_insn, at expr.c:3096
g++-version 4.0.3
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: kevin am 06. September 2007, 21:45
Also in LOST habe ich es so geschrieben, was auch am direktesten der Spezifikation entspricht:
asm("lidt %0" : : "m" (idt_ptr));
Titel: Re: Problem mit inlineassambler und lidt
Beitrag von: middle_endian am 06. September 2007, 23:43
das tut was es soll :)