我为什么要使用';rdtsc&x27;在x86和x86_x64上有什么不同?

我为什么要使用';rdtsc&x27;在x86和x86_x64上有什么不同?,c,cpu-registers,rdtsc,C,Cpu Registers,Rdtsc,我知道rdtsc将处理器时间戳计数器的当前值加载到两个寄存器中:EDX和EAX。为了在x86上使用它,我需要这样做(假设使用Linux): 对于x86_x64: unsigned long lo, hi; asm( "rdtsc" : "=a" (lo), "=d" (hi) ); return( lo | (hi << 32) ); 无符号长lo,hi; asm(“rdtsc”:“=a”(lo),“=d”(hi)); return

我知道
rdtsc
将处理器时间戳计数器的当前值加载到两个寄存器中:EDX和EAX。为了在x86上使用它,我需要这样做(假设使用Linux):

对于x86_x64:

        unsigned long lo, hi;
        asm( "rdtsc" : "=a" (lo), "=d" (hi) ); 
        return( lo | (hi << 32) );
无符号长lo,hi;
asm(“rdtsc”:“=a”(lo),“=d”(hi));

return(lo |)(hi在x86-64模式下,RDTSC还清除RAX的较高32位。为了补偿这些位,我们必须将hi向左移动32位。

区别不在于
RDTSC
,而在于Linux内核想用它做什么

在32位中,它返回一个32位的值。因此eax中的值足够好了。

在64位中,它返回一个64位的值。因此它需要合并两个寄存器的值。

我完全正确,
rdtsc
将处理器时间戳计数器的当前值加载到两个寄存器中:EDX和EAX,而不是从EAX加载到EDX的寄存器中?(EAX、EBX、ECX、EDX)rdtsc始终返回64位值,因此对于32位机器,它将存储到EDX和EAX中,是的,您是对的。根据,即使在32位操作系统中,
\u asm\u\u volatile\u(“rdtsc”:“=A”(勾号))也会返回64位值
。在引用的链接中搜索
rdtsc
。@wlnirvana,这是在32位上获得64位时间戳的一个好方法。但是Linux选择使用
long
,所以只需要32位。@ugoren您能详细说明一下“Linux选择使用
long
”吗?@wlnirvana,函数返回
long
,在32位系统上是32位的。这是开发人员选择定义它的方式。你是指OP使用的函数,返回
lo
?是的,当然是32位。但是如果使用gcc文档中的样式,我认为会返回64位值?这些定义缺失
volatile
在asm上;如果编译器可以看到开始和结束,那么它们在计时上就不安全。我想知道这在Linux中是否是故意的,因为它们从来没有在内核中使用它进行微基准标记?但是IDK在Linux中它可以有效地使用CSE。TL:DR:您不应该以不同的方式使用它。请参阅适用于32位和64位的asm。(我的回答显示了如何使用
\uu rdtsc()
内在函数)。
        unsigned long lo, hi;
        asm( "rdtsc" : "=a" (lo), "=d" (hi) ); 
        return( lo | (hi << 32) );