2

I'm using the rdtscp instruction to read the ecx register for detecting cpu and numa node ids (I'm developing an os).

The code looks like the following

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

On using this function, I have a not understandable behaviour: The CPU tells me a lot of exceptions (page fault, general protection fault, ...). That indicates to me, that the cpu or node id is not read, but if I log the id, all seems right and no exception appears.

So in code:

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

but

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

Is the cpu reordering my instructions, so that he will use cpu_id/numa_id before reading it?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
jagemue
  • 363
  • 4
  • 16

1 Answers1

2

Tell the compiler that the registers eax and edx are clobbered. Add them to the clobbered list:

__asm__ __volatile__("rdtscp\n" : "=c" (p) : : "memory", "eax", "edx");
The Techel
  • 918
  • 8
  • 13
  • 1
    Why do you clobber "memory" here? This instruction does not clobber memory. And I guess you are assuming here that the Intel dialect has been specified (`-masm=intel`); probably worth calling out explicitly, as this won't work otherwise. – Cody Gray - on strike Jul 06 '17 at 11:13