Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 组装如何使用SIDT或LIDT?_C_Assembly_X86 64_Inline Assembly - Fatal编程技术网

C 组装如何使用SIDT或LIDT?

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;

我在读:

但我有一个问题,我应该把钱存到哪里

我不知道我要保存的内存是否为空以供使用,或者它是否在范围内。那么我应该如何选择那个内存区域呢

为什么?

我正在编写自己的函数来存储idt电阻(大小为80位),然后编写另一个函数来加载它

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,了解上的全部函数)另请参见


那么您正在编写自己的操作系统,以便可以在内核模式下运行它?请参阅GCC手册()并了解如何使用
“=m”(*idtr)
内存输出操作数,假设这是GCC/clang。不要破坏您的帖子。如果要删除它,请使用“删除”按钮。如果该选项不可用,则不允许删除该内容。谢谢,似乎我问了错误的问题(考虑到您的努力,不会删除此选项)。请参阅:刚刚注意到,使用
-masm=intel
,我们得到了
sidt XMMWORD PTR[rdi]
。(结构的大小,因为我们没有使用
\uuuuu属性(packed))
)GAS拒绝使用它。AT&T语法汇编良好;寻址模式不包括大小。因此,它不一定需要修复。还要注意,
sidt
也应该使用
asm volatile
,因为它从源(IDTR)读取数据,在不同的执行中可能会有所不同。因此,它不是输入的纯函数,也就是说,在程序运行期间,不会每次都产生相同的值。