assembly 在MASM中将rdpmc_reference_cycles转换为64位

t40tm48m  于 2023-08-06  发布在  其他
关注(0)|答案(2)|浏览(116)

我一直在使用以下汇编语言代码,通过RDPMC指令读取性能监视计数器:

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

字符串
这在32位环境下工作正常,但现在我正在过渡到64位系统,我在调整代码时遇到了麻烦。在rdpmc指令之后,eax中的32位值包含结果的下半部分,edx中的32位值包含上半部分。
我需要合并这两个32位值以产生64位结果。但是,我不知道如何在MASM中实现这一点。我尝试了一些方法,但它们并没有像预期的那样工作。谁能指导我如何修改这段代码,使其产生64位的结果?

goucqfw6

goucqfw61#

RDPMC指令的输入仅依赖于ECX寄存器(在64位环境中,忽略RCX的高位双字)。结果在EDX:EAX中返回,RAX和RDX的高双字重置为零。
你的密码

mov ecx, 1h
shl ecx, 30
add ecx, 2
xor eax, eax
xor edx, edx
rdpmc

字符串
是复杂的,因为

  • 它使用3条指令来加载ECX,而不是一条mov ecx, 40000002h(相当于mov ecx, (1<<30) + 2)。
  • 它清除RAX和RDX没有好的理由

因此,要读取计数器并在单个RAX寄存器中提供64位结果,可以执行以下操作:

mov   ecx, (1<<30) + 2
rdpmc                   ; -> EDX:EAX
shl   rdx, 32
or    rax, rdx


shl rdx, 32将EDX的内容转换为RDX的高双字。
or rax, rdx在RAX中组合了两个双字。
值得注意的是,or只能很好地工作,因为shl使RDX的低dword为零,并且因为rdpmc使RAX的高dword为零。

tzcvj98z

tzcvj98z2#

我感谢大家花时间阅读和考虑我的问题。我一直在努力使用RDPMC指令将我的32位汇编代码适应64位环境,特别是将来自EAX和EDX寄存器的32位结果组合成64位结果。
经过进一步的研究和试验,我终于找到了一个有效的解决方案。下面是代码的修改版本,它成功地将结果组合成一个完整的64位结果

rdpmc_reference_cycles proc
    mov ecx, 1h
    shl ecx, 30
    add ecx, 2
    xor eax, eax
    xor edx, edx
    rdpmc
    shl rdx, 32          ; Shift the high 32 bits to their place
    or rax, rdx          ; Combine the high 32 bits (now in rdx) and low 32 bits (in eax)
    ret
rdpmc_reference_cycles endp

字符串
在这个解决方案中,我将EDX中的高32位移动到64位数字(RDX)中的适当位置。在这个移位之后,我将得到的RDX与来自EAX的低32位合并(或运算)。这样,我就可以在RAX中形成一个完整的64位结果。
我希望这个解决方案可以帮助其他可能面临类似问题的人。我欢迎社区提出任何进一步的见解或建议。谢谢你,谢谢

相关问题