C 奇怪的行为-获取GDT@inline程序集
在开始之前,这里提到的所有代码都运行@ring0(内核模式)-OSX 10.9: 以下函数崩溃:C 奇怪的行为-获取GDT@inline程序集,c,inline-assembly,C,Inline Assembly,在开始之前,这里提到的所有代码都运行@ring0(内核模式)-OSX 10.9: 以下函数崩溃: UINT64 GetGdtBase() { UINT64 gdt = 0; asm("sgdt %0\n" ::"m"(gdt)); return gdt >> 16; } 以下函数运行正常: UINT64 GetGdtBase(UINT64* result) { asm("sgdt %0\n" ::"m"(*result)); *result
UINT64 GetGdtBase()
{
UINT64 gdt = 0;
asm("sgdt %0\n" ::"m"(gdt));
return gdt >> 16;
}
以下函数运行正常:
UINT64 GetGdtBase(UINT64* result)
{
asm("sgdt %0\n" ::"m"(*result));
*result >>= 16;
return *result;
}
嗯,对我来说这看起来有点滑稽和怪异,但也许你们会发现我在这里做的事情有问题
我想听听你的建议
感谢在长模式(64位代码)下,sgdt
指令存储64位“GDT线性地址”和16位“GDT限制”。这将占用10个字节,不适合UINT64
对于代码的第一个版本,您将破坏堆栈。很可能破坏函数的返回地址并导致崩溃
对于代码的第二个版本,您仍然会破坏一些东西;但是任何被破坏的东西都可能不会被使用。在长模式(64位代码)中,sgdt
指令存储64位“GDT线性地址”和16位“GDT限制”。这将占用10个字节,不适合UINT64
对于代码的第一个版本,您将破坏堆栈。很可能破坏函数的返回地址并导致崩溃
对于代码的第二个版本,您仍然会破坏一些东西;但是任何被破坏的东西都可能不会被使用。在长模式(64位代码)中,sgdt
指令存储64位“GDT线性地址”和16位“GDT限制”。这将占用10个字节,不适合UINT64
对于代码的第一个版本,您将破坏堆栈。很可能破坏函数的返回地址并导致崩溃
对于代码的第二个版本,您仍然会破坏一些东西;但是任何被破坏的东西都可能不会被使用。在长模式(64位代码)中,sgdt
指令存储64位“GDT线性地址”和16位“GDT限制”。这将占用10个字节,不适合UINT64
对于代码的第一个版本,您将破坏堆栈。很可能破坏函数的返回地址并导致崩溃
对于代码的第二个版本,您仍然会破坏一些东西;但不管什么垃圾都不能用。1。第二个版本在不崩溃的意义上运行良好,还是在做你期望的事情的意义上运行良好?2.如果我正确理解了
asm::
,它希望输入地址在第二个之后,因此gdt
或*result
是一个输入,而不是一个结果。如果是这样的话,你不想用一个:
来表示一个结果地址吗?这是一种不会崩溃的感觉。第一辆撞坏了。第二个版本在不崩溃的意义上运行良好,还是在做你期望的事情的意义上运行良好?2.如果我正确理解了asm::
,它希望输入地址在第二个之后,因此gdt
或*result
是一个输入,而不是一个结果。如果是这样的话,你不想用一个:
来表示一个结果地址吗?这是一种不会崩溃的感觉。第一辆撞坏了。第二个版本在不崩溃的意义上运行良好,还是在做你期望的事情的意义上运行良好?2.如果我正确理解了asm::
,它希望输入地址在第二个之后,因此gdt
或*result
是一个输入,而不是一个结果。如果是这样的话,你不想用一个:
来表示一个结果地址吗?这是一种不会崩溃的感觉。第一辆撞坏了。第二个版本在不崩溃的意义上运行良好,还是在做你期望的事情的意义上运行良好?2.如果我正确理解了asm::
,它希望输入地址在第二个之后,因此gdt
或*result
是一个输入,而不是一个结果。如果是这样的话,你不想用一个:
来表示一个结果地址吗?这是一种不会崩溃的感觉。第一个崩溃了