2017-07-06 106 views
2

我正在使用rdtscp指令读取ecx寄存器以检测cpu和numa节点ID(我正在开发OS)。RDTSCP和指令顺序

的代码如下所示

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之前读它?

+2

好像你不告诉编译器eax和edx也被破坏了。 –

+0

是的,谢谢,修复它! – jagemue

+0

让我快点写一个答案..... –

回答

2

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

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

为什么你在这里打破“记忆”?这条指令不会破坏内存。我想你在这里假设已经指定了英特尔方言('-masm = intel');或许值得大声呼唤,否则这种方式无效。 –