c语言 - 使用 MinGW 的 GCC 内联组件加载 IDT 结构失败



尝试使用以下代码获取中断描述符的数据:

/* 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");

我有以下错误:

||=== Build: Release in driver2 (compiler: gnu_64) ===|
objReleasedriver.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)) ===|

使用mingw-64bit的G 编译器

gcc与MSVC不同,在内联汇编内不支持本地变量(在功能内部)。如果变量idt_info是全球的,则应该在内联汇编中可见,但是 gcc 文档劝阻以下内容:

在不使用输入/输出操作数的情况下访问数据(例如,直接使用汇编器模板中的全局符号)可能无法正常工作。同样,直接从汇编模板调用函数需要详细了解目标汇编器和ABI。

由于GCC没有解析汇编模板,因此它没有参考的任何符号的可见性。这可能会导致海湾合作委员会丢弃这些符号,除非它们也被列为输入,输出或goto操作数。

您想做的是使用 gcc 扩展的汇编模板,然后使用输出约束来允许 gcc 传递在idt_info的地址中,该地址将通过<<em> sidt 。这样的事情应该有效:

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

=表示约束将用于输出,m FORES gcc 以传递内存操作数。 sidt 需要一个内存操作数,而不是寄存器。 %[idtptr]是给出参数的名称, gcc 将用实际的内存参考替换。

最新更新