2017-07-06 617 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');或許值得大聲呼喚,否則這種方式無效。 –