I've been using the following code in assembly language to read performance-monitoring counters using the RDPMC instruction:
rdpmc_reference_cycles proc
mov ecx, 1h
shl ecx, 30
add ecx, 2
xor eax, eax
xor edx, edx
rdpmc
ret
rdpmc_reference_cycles endp
This works fine for a 32-bit environment, but now I'm transitioning to a 64-bit system and I'm having trouble adapting the code. After the rdpmc instruction, the 32-bit value in eax contains the lower half of the result, and the 32-bit value in edx contains the upper half.
I need to combine these two 32-bit values to produce a 64-bit result. However, I'm not sure how to achieve this in MASM. I've tried a few approaches, but they didn't work as expected. Could anyone guide me on how to modify this code so that it produces a 64-bit result?
The RDPMC instruction only depends on the ECX register for an input (in the 64-bit environment the high dword of RCX is ignored). And the result is returned in EDX:EAX with the high dwords of RAX and RDX reset to zero.
Your code
is convoluted because
mov ecx, 40000002h(equivalent tomov ecx, (1<<30) + 2).So to read the counter and deliver the 64-bit result in the single RAX register, you can do:
The
shl rdx, 32shifts the contents of EDX into the high dword of RDX.The
or rax, rdxcombines both dwords in RAX.It is important to note that this
orcould only work well because theshlmade the low dword of RDX zero, and because therdpmcmade the high dword of RAX zero.