我遇到了这段代码,需要了解它在做什么。它似乎只是声明了两个字节然后什么也没做......
uint64_t x;
__asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (x));
谢谢!
答案 0 :(得分:11)
这会直接在代码流中生成两个字节(0F 31)。这是一条RDTSC指令,它将时间戳计数器读入EDX:EAX,然后通过输出约束“= A”(x)将其复制到变量'x'
答案 1 :(得分:4)
0F 31是RDTSC(读时间戳计数器)指令的x86操作码;它将读取的值放入EDX和EAX寄存器。
_ _ asm__指令不只是声明两个字节,而是将内联汇编放入C代码中。据推测,该程序有一种方法可以在之后立即使用这些寄存器中的值。
答案 2 :(得分:2)
它正在插入一个0F 31操作码,根据this site是:
0F 31 P1+ f2 RDTSC EAX EDX IA32_T... Read Time-Stamp Counter
然后将结果存储在x
变量
答案 3 :(得分:0)
它是内联asm for rdtsc
,其中编写的机器代码编码用于支持不知道助记符的真正旧的汇编程序。
不幸的是,它只能在32位代码中正常工作,因为"=A"
在64位代码中不会将64位操作数分成两半。 (gcc manual even uses rdtsc
an an example to illustrate this)
使用gcc -m32或-m64编写此代码的安全方法是:
#include <stdint.h>
uint64_t timestamp_safe(void)
{
unsigned long tsc_low, tsc_high; // not uint32_t: saves a zero-extend for -m64 (but not x32 :/)
asm volatile("rdtsc" : "=d"(tsc_high), "=a" (tsc_low));
return ((uint64_t)tsc_high << 32) | tsc_low;
}
在32位代码中,它只是rdtsc
/ ret
,但在64位代码中,它会执行必要的移位/或将两半都归入rax
作为返回值。