奇怪的行为 - 获得GDT @内联汇编

时间:2014-10-06 08:34:31

标签: c inline-assembly

在开始之前,这里提到的所有代码都在运行@ ring0(内核模式) - OSX 10.9:

以下功能CRASHES:

UINT64 GetGdtBase()
{
    UINT64 gdt = 0;
    asm("sgdt %0\n" ::"m"(gdt));
    return gdt >> 16;
}

以下函数运行FINE:

UINT64 GetGdtBase(UINT64* result)
{
    asm("sgdt %0\n" ::"m"(*result));
    *result >>= 16;
    return *result;
}
嗯,它看起来很有趣&对我来说很奇怪,但也许你们会发现我在这里做错了。

很想听听一些建议。

感谢

1 个答案:

答案 0 :(得分:3)

在长模式(64位代码)中,sgdt指令存储64位“GDT的线性地址”和16位“GDT限制”。这需要10个字节,不适合UINT64。

对于代码的第一个版本,您将丢弃堆栈。很可能会破坏函数的返回地址并导致崩溃。

对于代码的第二个版本,你仍然会捣乱一些东西;但无论如何都不会使用任何被破坏的东西。