2017-07-06 5 views
2

J'utilise l'instruction rdtscp pour lire le registre ecx pour détecter les ID de noeud cpu et numa (je développe un os).RDTSCP et ordre d'instruction

Le code ressemble à la

suivante
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; 
} 

En utilisant cette fonction, j'ai un comportement incompréhensible: Le CPU me dit beaucoup d'exceptions (faute de page, faute de protection générale, ...). Cela m'indique, que l'identifiant de cpu ou de noeud n'est pas lu, mais si je consignation l'identification, tout semble juste et aucune exception n'apparaît.

donc dans le code:

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

mais

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

est le cpu ReOrdering mes instructions, de sorte qu'il utilisera cpu_id/numa_id avant de le lire?

+2

il semble que vous ne dites pas que le compilateur EAX et EDX sont aussi bien soient faussés. –

+0

ouais, merci, ça l'a réparé! – jagemue

+0

permettez-moi d'écrire rapidement une réponse ..... –

Répondre

2

Dites au compilateur que les registres eax et edx sont clobulés. Ajoutez-les à la clobbered list:

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

Pourquoi classez-vous "mémoire" ici? Cette instruction ne bloque pas la mémoire. Et je suppose que vous supposez ici que le dialecte d'Intel a été spécifié ('-masm = intel'); Cela vaut probablement la peine d'être explicitement mentionné, car cela ne fonctionnera pas autrement. –