汇编指令:rdtsc

Assembler instruction: 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 , %%rdx\n\t"  // Shift the upper bits left.
               "or %%rdx, %0"        // 'Or' in the lower bits.
               : "=a" (msr)
               :
               : "rdx");

它与以下内容有何不同:

uint64_t msr;
asm volatile ( "rdtsc\n\t"
               : "=a" (msr));

为什么我们需要shift和or操作,最后的rdx是做什么的?

编辑:添加了对原始问题仍不清楚的内容。

只是回顾一下。第一行将时间戳加载到寄存器 eax 和 edx 中。第二行将 eax 中的值移位并存储在 rdx 中。第三行将 edx 中的值与 rdx 中的值进行 OR 运算,并将其保存在 rdx 中。第四行将 rdx 中的值分配给我的变量。最后一行将 rdx 设置为 0.

再次感谢! :)

EDIT2:回答了我的一些问题...

rdtsc returns 一对 32 位寄存器(EDX 和 EAX)中的时间戳。第一个片段将它们组合成单个 64 位寄存器 (RDX),该寄存器映射到 msr 变量。

第二个片段是错误的。我不确定会发生什么:要么根本不编译,要么只更新 msr 变量的一部分。

uint64_t msr;
asm volatile ( "rdtsc\n\t"    // Returns the time in EDX:EAX.
               "shl , %%rdx\n\t"  // Shift the upper bits left.
               "or %%rdx, %0"        // 'Or' in the lower bits.
               : "=a" (msr)
               :
               : "rdx");

因为 rdtsc 指令 returns 它的结果是 edxeax,而不是 64 位机器上的直接 64 位寄存器(参见intel 系统的编程手册了解更多信息;它是一条 x86 指令),第二 指令将 rdx 寄存器向左移动 32 位,以便 edx 位于高 32 位而不是低 32 位。
"=a" (msr) 会将 eax 的内容移动到 msr%0),即移动到它的低 32 位,所以总共有 edx(高 32 位)和 eax(低 32 位)到 rdxmsr.
rdx 是一个 clobber,它将代表 msr C 变量。

这类似于在 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;
}

并且:

uint64_t msr;
asm volatile ( "rdtsc\n\t"
               : "=a" (msr));

这个,就是把eax的内容给你变成msr

编辑:

1) "\n\t" 是为了使生成的程序集看起来更清晰 error-free,这样你就不会得到像 movl , %eaxmovl , %ebx
这样的东西 2)末尾的rdx是否等于0?左移就是这样做的,它去掉了已经在rdx.
中的位 3) a实际上是eax和d - edx吗?这是hard-coded吗?是的,有一个table描述什么字符代表什么寄存器,例如"D" 将是 rdi,"c" 将是 ecx,...