使用 MinGW 的 GCC 内联汇编加载 IDT 结构失败
Using MinGW's GCC inline assembly to load IDT structure fails
尝试使用以下代码获取中断描述符 Table 的数据:
/* 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) ===|
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)) ===|
使用 MinGW-64bit 的 g++ 编译器
与 MSVC 不同,GCC 不支持内联汇编中的局部变量(函数内部)。如果变量 idt_info
是全局的,那么它应该对内联程序集可见,但是 GCC documentation 不鼓励这样做:
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.
你想要做的是使用GCC extended assembler template并使用输出约束来允许GCC传入idt_info
的地址SIDT 更新。这样的事情应该有效:
__asm__ __volatile__ ("sidt %[idtptr]" : [idtptr]"=m"(idt_info));
=
表示约束将用于输出,m
强制GCC传递一个内存操作数。 SIDT 需要内存操作数而不是寄存器。 %[idtptr]
是给参数的名称,GCC 会用实际的内存引用替换它。
尝试使用以下代码获取中断描述符 Table 的数据:
/* 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) ===|
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)) ===|
使用 MinGW-64bit 的 g++ 编译器
与 MSVC 不同,GCC 不支持内联汇编中的局部变量(函数内部)。如果变量 idt_info
是全局的,那么它应该对内联程序集可见,但是 GCC documentation 不鼓励这样做:
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.
你想要做的是使用GCC extended assembler template并使用输出约束来允许GCC传入idt_info
的地址SIDT 更新。这样的事情应该有效:
__asm__ __volatile__ ("sidt %[idtptr]" : [idtptr]"=m"(idt_info));
=
表示约束将用于输出,m
强制GCC传递一个内存操作数。 SIDT 需要内存操作数而不是寄存器。 %[idtptr]
是给参数的名称,GCC 会用实际的内存引用替换它。