Jam*_*mes 14 assembly gcc x86-64 inline-assembly
免责声明:单词无法描述我厌恶AT&T风格的语法
我有一个问题,我希望是由寄存器clobbering引起的.如果没有,我有一个更大的问题.
我使用的第一个版本是
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);
}
Run Code Online (Sandbox Code Playgroud)
我注意到这个版本中没有'破坏'的东西.这是否是一个我不知道的问题...我想这取决于编译器是否内联函数.使用此版本会导致我无法始终重现的问题.
我发现的下一个版本是
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;
}
Run Code Online (Sandbox Code Playgroud)
这是令人安心的不可读和官方的看,但就像我说我的问题并不总是可重复的所以我只是试图排除我的问题的一个可能的原因.
我认为第一个版本存在问题的原因是它覆盖了以前持有函数参数的寄存器.
什么是正确的...版本1,或版本2,或两者兼而有之?
amd*_*mdn 20
这是C++代码,它将返回TSC并将辅助32位存储到引用参数中
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;
}
Run Code Online (Sandbox Code Playgroud)
最好在C++语句中进行shift
并add
合并两个32位的一半,而不是内联,这允许编译器按照它认为合适的方式调度这些指令.
归档时间: |
|
查看次数: |
8350 次 |
最近记录: |