RDTSCP和指令顺序

时间:2017-07-06 10:23:50

标签: c++ assembly x86 inline-assembly osdev

我正在使用rdtscp指令读取ecx寄存器以检测cpu和numa node id(我正在开发一个操作系统)。

代码如下所示

inline static long get(unsigned char *node_id = 0, unsigned char *cpu_id = 0)
{
    unsigned int p;
    __asm__ __volatile__("rdtscp\n" : "=c" (p) : : "memory");

    if (node_id) {
        *node_id = p >> 12;
    }

    if (cpu_id) {
        *cpu_id = p & 0xfff;
    }

    return 0;
}

使用此功能时,我有一个不可理解的行为:CPU告诉我很多异常(页面错误,一般保护错误,......)。这告诉我,没有读取cpu或节点id,但是如果我记录了id,那么一切似乎都没有,并且没有异常出现。

所以在代码中:

// ...
unsigned char cpu, numa;
get(&numa, &cpu);
// use cpu and numa id creates exception

// ...
unsigned char cpu, numa;
get(&numa, &cpu);
print(cpu); // <--- this makes cpu reading ok?
// use cpu and numa id is ok

cpu是否重新排序我的指令,以便在阅读之前使用cpu_id / numa_id?

1 个答案:

答案 0 :(得分:2)

告诉编译器寄存器eax和edx被破坏了。将它们添加到clobbered list

__asm__ __volatile__("rdtscp\n" : "=c" (p) : : "memory", "eax", "edx");