gpt4 book ai didi

gcc - 哪个内联汇编代码对于 rdtscp 是正确的?

转载 作者:行者123 更新时间:2023-12-02 20:21:03 25 4
gpt4 key购买 nike

免责声明:言语无法描述我对 AT&T 风格语法的厌恶程度

我遇到了一个问题,希望是由寄存器破坏引起的。如果没有,我就有一个更大的问题。

我使用的第一个版本是

static unsigned long long rdtscp(void)
{
unsigned int hi, lo;
__asm__ __volatile__("rdtscp" : "=a"(lo), "=d"(hi));
return (unsigned long long)lo | ((unsigned long long)hi << 32);
}

我注意到这个版本中没有“破坏”的东西。我不知道这是否是一个问题...我想这取决于编译器是否内联该函数。使用此版本会给我带来一些问题,这些问题并不总是可重现

我找到的下一个版本是

static unsigned long long rdtscp(void)
{
unsigned long long tsc;
__asm__ __volatile__(
"rdtscp;"
"shl $32, %%rdx;"
"or %%rdx, %%rax"
: "=a"(tsc)
:
: "%rcx", "%rdx");

return tsc;
}

这是令人放心的不可读和官方的外观,但就像我说的,我的问题并不总是可重现的,所以我只是试图排除我的问题的一个可能原因。

相信第一个版本存在问题的原因是它覆盖了以前保存函数参数的寄存器。

什么是正确的...版本 1 或版本 2,或两者都正确?

最佳答案

以下 C++ 代码将返回 TSC 并将辅助 32 位(处理器 ID)存储到引用参数中

static inline uint64_t rdtscp( uint32_t & aux )
{
uint64_t rax,rdx;
asm volatile ( "rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : : );
return (rdx << 32) + rax;
}

最好使用 shiftadd 来合并 C++ 语句中的两个 32 位半部分,而不是内联,这允许编译器按原样安排这些指令认为合适。

关于 aux 的更新:RDTSCP 指令返回 TSC(在两个寄存器中),并在第三个寄存器中返回处理器 ID (aux)(与仅返回 TSC 的 RDTSC 指令不同)。处理器ID是一个MSR(机器特定寄存器),因此必须由特权系统软件初始化,其目的是识别哪个“核心”正在执行指令。因此该值取决于操作系统。

参见http://felixcloutier.com/x86/rdtscp

关于gcc - 哪个内联汇编代码对于 rdtscp 是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14783782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com