C 组装如何使用SIDT或LIDT?
我在读: 但我有一个问题,我应该把钱存到哪里 我不知道我要保存的内存是否为空以供使用,或者它是否在范围内。那么我应该如何选择那个内存区域呢 为什么? 我正在编写自己的函数来存储idt电阻(大小为80位),然后编写另一个函数来加载它C 组装如何使用SIDT或LIDT?,c,assembly,x86-64,inline-assembly,C,Assembly,X86 64,Inline Assembly,我在读: 但我有一个问题,我应该把钱存到哪里 我不知道我要保存的内存是否为空以供使用,或者它是否在范围内。那么我应该如何选择那个内存区域呢 为什么? 我正在编写自己的函数来存储idt电阻(大小为80位),然后编写另一个函数来加载它 void my_store_idt(struct desc_ptr *idtr) { asm ("SIDT " ); } 你有两个选择。或者让调用方给您一个存储描述的位置: struct idt { void *base;
void my_store_idt(struct desc_ptr *idtr) {
asm ("SIDT "
);
}
你有两个选择。或者让调用方给您一个存储描述的位置:
struct idt {
void *base;
unsigned short length;
};
void my_store_idt(struct idt *idt)
{
asm volatile ("sidt %0" : "=m"(*idt));
}
或者自己分配结构并按值返回:
struct idt my_store_idt(void)
{
struct idt idt;
asm volatile ("sidt %0" : "=m"(idt));
return (idt);
}
使用volatile
可以确保编译器不会假设每次都读取相同的IDTR
以类似的方式加载IDT,但使用输入操作数而不是输出操作数:
asm volatile ("lidt %0" :: "m"(idt));
我不知道我要保存的内存是否为空以供使用,或者它是否在范围内
在C语言中,使用struct desc_ptr idtr
变量(本地或全局,无所谓)为stuff保留空间是一件事,您可以将其地址传递给此函数。就像任何其他函数一样,您向其传递指向空间的指针以存储输出。事实上,您通过内联asm对空间进行实际写入,这与此函数作为大型C程序的一部分的工作方式没有任何区别。(我猜是内核,因为lidt
是一条特权指令)
@fuz的回答显示了正确的GNU C内联asm语法,并带有“=m”(*idtr)
,告诉编译器内存中的C变量是输出操作数,让它选择寻址模式。(查看编译器生成的asm,了解上的全部函数)另请参见
“=m”(*idtr)
内存输出操作数,假设这是GCC/clang。不要破坏您的帖子。如果要删除它,请使用“删除”按钮。如果该选项不可用,则不允许删除该内容。谢谢,似乎我问了错误的问题(考虑到您的努力,不会删除此选项)。请参阅:刚刚注意到,使用-masm=intel
,我们得到了sidt XMMWORD PTR[rdi]
。(结构的大小,因为我们没有使用\uuuuu属性(packed))
)GAS拒绝使用它。AT&T语法汇编良好;寻址模式不包括大小。因此,它不一定需要修复。还要注意,sidt
也应该使用asm volatile
,因为它从源(IDTR)读取数据,在不同的执行中可能会有所不同。因此,它不是输入的纯函数,也就是说,在程序运行期间,不会每次都产生相同的值。