2016-11-25 2 views
1

In einem Versuch, die Interrupt Descriptor Table die Daten zu erhalten, mit dem folgenden Code:MinGW GCC Inline-Montage mit IDT-Struktur geladen werden kann

/* SIDT returns IDT in following format */ 
#pragma pack(1) 
typedef struct 
{ 
    unsigned short IDTLimit; 
    unsigned short LowIDTBase; 
    unsigned short HighIDTBase 

} s_idt_info; 
#pragma pack() 

. 
. 
. 

    s_idt_info idt_info;  // returned by sidt 
    s_idt_entry *idt_entries; // obtained from idt_info 
    unsigned long count; 

    // load idt_info 
    __asm ("sidt idt_info"); 

ich die folgende Fehlermeldung erhalten:

||=== Build: Release in driver2 (compiler: gnu_64) ===| 
obj\Release\driver.o:driver.c|| undefined reference to `idt_info'| 
||error: ld returned 1 exit status| 
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===| 

Mit MinGW -64bit's g ++ Compiler

+0

GCC ist kein "Inline Assembler" und das ist nicht mit Mingw! – Olaf

+0

Mögliches Duplikat von [Was ist ein nicht definierter Verweis/ein ungelöster externer Symbolfehler und wie behebe ich ihn?] (Http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-) symbol-error-and-how-do-i-fix) – Olaf

+2

Olaf: Ich denke nicht, dass dies ein Duplikat dieser Frage ist, da dies das Problem der GCC-Basis-Inline-Assemblierung ist, die nur globale Variablen sichtbar macht. In diesem Fall ist "idt_info" wahrscheinlich lokal für die Funktion, in der sich der Code befand (das ist ein wenig raten, da die Funktion nicht im Code angezeigt wird). –

Antwort

2

GCC unterstützt keine lokalen Variablen (innerhalb einer Funktion) innerhalb der Inline Assembly im Gegensatz zu MSVC. Wenn die Variable idt_info global gemacht wurden, dann sollte es jedoch auf den Inline-Assembler, sichtbar sein die GCC documentation dies schreckt:

Accessing data from C programs without using input/output operands (such as by using global symbols directly from the assembler template) may not work as expected. Similarly, calling functions directly from an assembler template requires a detailed understanding of the target assembler and ABI.

Since GCC does not parse the assembler template, it has no visibility of any symbols it references. This may result in GCC discarding those symbols as unreferenced unless they are also listed as input, output, or goto operands.

Was wollen Sie tun, ist eine GCC extended assembler template zu verwenden und eine Ausgabebedingung verwenden GCC ermöglichen zu geben Sie die Adresse idt_info ein, die von SIDT aktualisiert wird. So etwas sollte funktionieren:

__asm__ __volatile__ ("sidt %[idtptr]" : [idtptr]"=m"(idt_info)); 

Die = bezeichnet die Einschränkung wird für die Ausgabe verwendet werden, m Kräfte GCC einen Speicheroperanden passieren. SIDT erfordert einen Speicheroperanden und kein Register. %[idtptr] ist der Name für den Parameter und GCC wird es durch die tatsächliche Speicherreferenz ersetzen.

Verwandte Themen