汇编指令:rdtsc [英] Assembler instruction: rdtsc

查看:662
本文介绍了汇编指令:rdtsc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能帮助我理解 https://gcc.gnu中给出的汇编程序.org / onlinedocs / gcc / Extended-Asm.html



它是这样的:

  uint64_t msr; 
asm volatile(rdtsc\\\
\t//返回EDX中的时间:EAX
shl $ 32,%% rdx\\\
\t//将高位
或%% rdx,%0//'Or'位于低位
:= a(msr)

:rdx );

它与以下不同:

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

为什么我们需要移位和/或操作,最后rdx会做什么?



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




  • 什么是\ n \ t做什么?

  • 做什么?:做什么?


    • 分隔符输出/输入/ clobbers ...

    • rdx是否等于0?



    仅供参考。第一行加载寄存器eax和edx中的时间戳。第二行将eax中的值和rdx中的值存储在一起。第三行将edx中的值与rdx中的值相加并将其保存在rdx中。第四行将rdx中的值赋给我的变量。最后一行将rdx设置为0.




    • 为什么前三行没有:?


      • 它们是一个模板。输出:的第一行,第二行是可选输入,第三行是可选的clobbers列表(已更改的寄存器)。


    • 是一个真正的eax和d-edx吗?这是硬编码吗?



    再次感谢! :)



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

    解决方案

      uint64_t msr; 
    asm volatile(rdtsc\\\
    \t//返回EDX中的时间:EAX
    shl $ 32,%% rdx\\\
    \t//将高位
    或%% rdx,%0//'Or'位于低位
    := a(msr)

    :rdx );

    因为 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_ tax,edx;
    asm volatile(rdtsc\\\
    \t,= a(eax),= d(edx));
    return(uint64_t)eax | (uint64_t)edx<< 32;

    和:

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

    这个只会给你 eax 转换为 msr



    编辑: b
    1)\\\
    \t是为了让生成的程序集看起来更清晰,没有错误,这样就不会像 movl $ 1 ,%eaxmovl $ 2,%ebx

    2)结尾的rdx是否等于0?左移是否这样做,已经在 rdx

    3)是一个实际的eax和d-edx吗?这是硬编码的吗?是的,有一个表格描述了什么字符代表什么寄存器,例如D为 rdi ,c为 ecx ,...


    Could someone help me understand the assembler given in https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

    It goes like this:

    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");
    

    How is it different from:

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

    Why do we need shift and or operations and what does rdx at the end do?

    EDIT: added what is still unclear to the original question.

    • What does "\n\t" do?
    • What do ":" do?
      • delimiters output/input/clobbers...
    • Is rdx at the end equal to 0?

    Just to recap. First line loads the timestamp in registers eax and edx. Second line shifts the value in eax and stores in rdx. Third line ors the value in edx with the value in rdx and saves it in rdx. Fourth line assigns the value in rdx to my variable. The last line sets rdx to 0.

    • Why are the first three lines without ":"?
      • They are a template. First line with ":" is output, second is optional input and third one is optional list of clobbers (changed registers).
    • Is a actually eax and d - edx? Is this hard-coded?

    Thanks again! :)

    EDIT2: Answered some of my questions...

    解决方案

    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");
    

    Because the rdtsc instruction returns it's results in edx and eax, instead of a straight 64-bit register on a 64-bit machine (See the intel system's programming manual for more information; it's an x86 instruction), the 2nd instruction shifts the rdx register to the left 32 bits so that edx will be on the upper 32 bits instead of the lower 32 bits.
    "=a" (msr) will move the contents of eax into msr (the %0), i.e. into the lower 32 bits of it, so in total you have edx (higher 32 bits) and eax (lower 32 bits) into rdx which is msr.
    rdx is a clobber which will represent the msr C variable.

    It's similar to doing the following in 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;
    }
    

    And:

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

    This one, will just give you the contents of eax into msr.

    EDIT:

    1) "\n\t" is for the generated assembly to look clearer and error-free, so that you don't end up with things like movl $1, %eaxmovl $2, %ebx
    2) Is rdx at the end equal to 0? The left shift does this, it removes the bits that are already in rdx.
    3) Is a actually eax and d - edx? Is this hard-coded? Yes, there is a table that describes what characters represents what register, e.g. "D" would be rdi, "c" would be ecx, ...

    这篇关于汇编指令:rdtsc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆