【问题标题】:RDTSCP and Instruction order [duplicate]RDTSCP 和指令顺序 [重复]
【发布时间】:2017-12-10 07:21:01
【问题描述】:

我正在使用rdtscp 指令读取ecx 寄存器以检测cpu 和numa 节点ID(我正在开发一个操作系统)。

代码如下所示

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 也被破坏了。
  • 是的,谢谢,解决了!
  • 让我赶紧写一个答案.....

标签: c++ assembly x86 inline-assembly osdev


【解决方案1】:

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

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

【讨论】:

  • 你为什么要在这里破坏“内存”?该指令不会破坏内存。我猜你在这里假设英特尔方言已被指定(-masm=intel);可能值得明确指出,否则这将不起作用。
猜你喜欢
  • 2020-12-21
  • 2014-03-18
  • 2022-01-10
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多