在开始之前,这里提到的所有代码都在运行@ 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;
}
嗯,它看起来很有趣&对我来说很奇怪,但也许你们会发现我在这里做错了。
很想听听一些建议。
感谢
答案 0 :(得分:3)
在长模式(64位代码)中,sgdt
指令存储64位“GDT的线性地址”和16位“GDT限制”。这需要10个字节,不适合UINT64。
对于代码的第一个版本,您将丢弃堆栈。很可能会破坏函数的返回地址并导致崩溃。
对于代码的第二个版本,你仍然会捣乱一些东西;但无论如何都不会使用任何被破坏的东西。