RDTSCP 和指令顺序
RDTSCP and Instruction order
我正在使用 rdtscp
指令读取 ecx
寄存器以检测 cpu 和 numa 节点 ID(我正在开发一个 os)。
代码如下所示
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?
告诉编译器寄存器 eax 和 edx 被破坏了。将它们添加到 clobbered list:
__asm__ __volatile__("rdtscp\n" : "=c" (p) : : "memory", "eax", "edx");
我正在使用 rdtscp
指令读取 ecx
寄存器以检测 cpu 和 numa 节点 ID(我正在开发一个 os)。
代码如下所示
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?
告诉编译器寄存器 eax 和 edx 被破坏了。将它们添加到 clobbered list:
__asm__ __volatile__("rdtscp\n" : "=c" (p) : : "memory", "eax", "edx");