Let*_*eta 4 x86 assembly gcc timestamp rdtsc
有人可以帮我理解https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html中给出的汇编程序
它是这样的:
uint64_t msr;
asm volatile ( "rdtsc\n\t" // Returns the time in EDX:EAX.
"shl $32, %%rdx\n\t" // Shift the upper bits left.
"or %%rdx, %0" // 'Or' in the lower bits.
: "=a" (msr)
:
: "rdx");
Run Code Online (Sandbox Code Playgroud)
它与以下内容有何不同:
uint64_t msr;
asm volatile ( "rdtsc\n\t"
: "=a" (msr));
Run Code Online (Sandbox Code Playgroud)
为什么我们需要转移和/或操作以及rdx到底有什么作用?
编辑:添加了原始问题尚不清楚的内容.
回顾一下.第一行加载寄存器eax和edx中的时间戳.第二行将eax中的值移位并存储在rdx中.第三行将edx中的值与rdx中的值一起使用,并将其保存在rdx中.第四行将rdx中的值赋给我的变量.最后一行将rdx设置为0.
再次感谢!:)
EDIT2:回答了我的一些问题......
小智 7
uint64_t msr;
asm volatile ( "rdtsc\n\t" // Returns the time in EDX:EAX.
"shl $32, %%rdx\n\t" // Shift the upper bits left.
"or %%rdx, %0" // 'Or' in the lower bits.
: "=a" (msr)
:
: "rdx");
Run Code Online (Sandbox Code Playgroud)
因为rdtsc
指令返回它的结果在edx
与eax
,代替64位机器上的一个直的64位寄存器(请参阅Intel系统的编程手册的详细信息;它是一个x86指令),则第二指令将rdx
寄存器到左侧32这样的位edx
将位于高32位而不是低32位.
"=a" (msr)
将移动的内容的eax
入msr
(的%0
),即,进入它的低32位,所以在总你有edx
(较高的32位)和eax
(低32位)转换成rdx
其msr
.
rdx
是一个代表msr
C变量的clobber .
它与在C中执行以下操作类似:
static inline uint64_t rdtsc(void)
{
uint32_t eax, edx;
asm volatile("rdtsc\n\t", "=a" (eax), "=d" (edx));
return (uint64_t)eax | (uint64_t)edx << 32;
}
Run Code Online (Sandbox Code Playgroud)
和:
uint64_t msr;
asm volatile ( "rdtsc\n\t"
: "=a" (msr));
Run Code Online (Sandbox Code Playgroud)
这一次,只会给你的内容eax
进入msr
.
编辑:
1)"\n\t"是生成的程序集看起来更清晰,没有错误,所以你最终得不到像movl $1, %eaxmovl $2, %ebx
2)rdx末尾是否等于0?左移这样做,它删除了已经存在的位rdx
.
3)实际上是eax和d - edx吗?这是硬编码的吗?是的,有一个表格描述了哪些字符代表哪个寄存器,例如"D"将是rdi
,"c"将是ecx
,......