【问题标题】:How can I convert this assembly timestamp function to C++? [duplicate]如何将此程序集时间戳函数转换为 C++? [复制]
【发布时间】:2015-12-15 19:39:26
【问题描述】:

我正在尝试将别人的项目从 32 位转换为 64 位。一切似乎都很好,除了一个函数,它使用了 Visual Studio 在构建 x64 时不支持的汇编表达式:

// Returns the Read Time Stamp Counter of the CPU
// The instruction returns in registers EDX:EAX the count of ticks from processor reset.
// Added in Pentium. Opcode: 0F 31.
int64_t CDiffieHellman::GetRTSC( void )
{
    int tmp1 = 0;
    int tmp2 = 0;

#if defined(WIN32)
    __asm
    {
        RDTSC;          // Clock cycles since CPU started
        mov tmp1, eax;
        mov tmp2, edx;
    }
#else
    asm( "RDTSC;\n\t"
        "movl %%eax, %0;\n\t"
        "movl %%edx, %1;" 
        :"=r"(tmp1),"=r"(tmp2)
        :
        :
        );
#endif

    return ((int64_t)tmp1 * (int64_t)tmp2);
}

最有趣的是,它被用于生成随机数。 asm 块都不能在 x64 下编译,所以玩 ifdef 并没有帮助。我只需要找到 C/C++ 替换以避免重写整个程序。

【问题讨论】:

    标签: c++ inline-assembly rdtsc


    【解决方案1】:

    对于 Windows 分支,

    #include <intrin.h>
    

    并调用__rdtsc() 内部函数。

    文档on MSDN

    对于 Linux 分支,intrinsic 在同名下可用,但需要不同的头文件:

    #include <x86intrin.h>
    

    【讨论】:

    • 但是有这样的事情......原始代码以某种方式使用了 2 个整数,然后将它们相乘。我不确定该操作的结果是什么 - 以及如何使用该单个时间戳来执行此操作。到目前为止,我将按原样返回时间戳。
    • @TomášZato:正如您在评论中看到的(这是正确的),结果的高 32 位以EDX 结尾,而低 32 位以EAX 结尾。所以__rdtsc()intrinsic 会给你真正的时间戳,即(EDX &lt;&lt; 32ULL) | EAX。要重现原始公式,您将使用uint64_t tsc = __rdtsc(); return (tsc &gt;&gt; 32) * (tsc &amp; 0xFFFFFFFF);,但这比原始公式更随机且不统一,所以......我认为最好不要做乘法。
    猜你喜欢
    • 2017-05-20
    • 2014-01-23
    • 2017-05-11
    • 1970-01-01
    • 2017-08-11
    • 2021-04-17
    • 2015-07-07
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多