what is the C++ equivalent for this assembly code

223 Views Asked by At

I'm trying to figure out how to read this assembly code in C++.

This is the code:

unsigned __int64 high_perf_time;
unsigned __int64 *dest = &high_perf_time;
__asm 
{
    _emit 0xf        // these two bytes form the 'rdtsc' asm instruction,
    _emit 0x31       //  available on Pentium I and later.
    mov esi, dest
    mov [esi  ], eax    // lower 32 bits of tsc
    mov [esi+4], edx    // upper 32 bits of tsc
}
__int64 time_s     = (__int64)(high_perf_time / frequency);  // unsigned->sign conversion should be safe here
__int64 time_fract = (__int64)(high_perf_time % frequency);  // unsigned->sign conversion should be safe here

I know 0xf 0x31 is rdtsc eax, edx, but what is mov esi,dest? How can I write that in C++?

2

There are 2 best solutions below

3
Ben Voigt On BEST ANSWER

The C++ code is

#include <intrin.h>
unsigned __int64 high_perf_time = __rdtsc();

Documentation here: https://learn.microsoft.com/en-us/cpp/intrinsics/rdtsc

But you probably want QueryPerformanceCounter() and QueryPerformanceFrequency() instead, else you will have a race condition if your thread is scheduled on a different processor core between successive __rdtsc() calls.

2
Martin Rosenau On

If you want to understand what these three instructions do:

The following three instructions:

    mov esi, dest
    mov [esi  ], eax    // lower 32 bits of tsc
    mov [esi+4], edx    // upper 32 bits of tsc

... are the equivalent of the following C++ code:

    uint32_t * esi = (uint32_t *)dest;
    esi[0] = eax;
    esi[1] = edx;

And because the x86 CPUs are "little-endian", this is equal to:

    *dest = (((__int64_t)edx)<<32) + (uint32_t)eax;

... however, because you cannot access the eax and edx registers directly using C++, this operation must be done in assembly code.