繁体   English   中英

这个x86内联汇编在做什么?

[英]What is this x86 inline assembly doing?

我遇到了这段代码,需要了解它在做什么。 它似乎只是宣布两个字节,然后什么都不做......

uint64_t x;
__asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (x));

谢谢!

这将直接在代码流中生成两个字节(0F 31)。 这是一条RDTSC指令,它将时间戳计数器读入EDX:EAX,然后通过输出约束“= A”(x)将其复制到变量'x'

0F 31是RDTSC(读时间戳计数器)指令的x86操作码; 它将读取的值放入EDX和EAX寄存器。

_ _ asm__指令不只是声明两个字节,而是将内联汇编放入C代码中。 据推测,该程序有一种方法可以在之后立即使用这些寄存器中的值。

http://en.wikipedia.org/wiki/Time_Stamp_Counter

它正在插入一个0F 31操作码,根据这个站点是:

0F 31   P1+   f2   RDTSC EAX EDX IA32_T...        Read Time-Stamp Counter 

然后它将结果存储在x变量中

它是rdtsc的内联asm,其中编写的机器代码编码支持真正不知道助记符的旧汇编程序。

不幸的是,它只能在32位代码中正常工作,因为"=A"在64位代码中不会将64位操作数分成两半。 gcc手册甚至使用rdtsc作为一个例子来说明这一点

编写此代码的安全方法是使用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作为返回值。

Godbolt编译器资源管理器上看到它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM