我在我的Fedora系统上的VMware上运行一个Ubuntu服务器VM,我想检索我的主机的TSC值.根据VMware,我可以通过执行RDPMC 0x10000来做到这一点.这在C++中使用内联汇编可以工作,但现在我需要在Go中执行相同的操作.

基本上,我的代码逻辑驻留在两个文件中.在.s文件中,我有以下内容:

#include "textflag.h"

// func rdPmcTsc() uint64
TEXT ·rdPmcTsc(SB), NOSPLIT, $0
    MOVL $0x10000, CX
    RDPMC
    RET

我将其链接到一个.go文件中,如下所示:

//go:nosplit
func rdPmcTsc() uint64

我一直在VScode上调试它,看看AX和DX寄存器中的值,汇编代码似乎可以正常工作.然而,一旦我需要使用Go中的值,它就会将25Ti左右的值转换为8000左右的值,并出现其他类似的错误. 我已经环顾四周很久了,但我没有找到任何合理的解释来解释为什么会发生这种情况.而且,据我所知,我试图获取RDPMC0x10000值的方法似乎就是在GO中应该如何完成它.

如果有人知道如何在围棋中获得正确的返回值,知道为什么它可能不起作用或诸如此类的事情,那就太好了.

推荐答案

设法把它修好了.原来,结果需要存储在RET之前,才能让围棋检索到它.此外,RIX和RDX的32位必须组合在一起才能得到完整的TSC结果.以下汇编程序代码修复了该问题:

#include "textflag.h"

// func rdPmcTsc() uint64
TEXT ·rdPmcTsc(SB), NOSPLIT, $0
    MOVL $0x10000, CX
    RDPMC
    SHLQ $32, DX       // Shift the higher bits in rdx
    ORQ DX, AX         // Combine the 2 registers for the 64 bits result
    MOVQ AX, ret+0(FP) // Store the result
    RET

Go相关问答推荐

Go -SDP服务器读缓冲区不会更改任何内容

编辑时保留YAML文件中的单引号

GO框架Echo中间件的使用

Date.Format正在输出非常奇怪的日期

JWT 如何解析声明有效性和错误?

如何根据中间件的请求设置上下文值?获取 go-staticcheck 问题

Go 中的sync.Cond 与 Wait 方法

Golang Docker Selenium Chrome

当图像是对象数组的元素时,如何显示存储为页面资源的图像?

如果值为 false,gRPC 不返回布尔值

regex.ReplaceAll 但如果替换则添加相同数量的字符

在嵌套模板中使用变量,它也被定义为 go 模板中的变量?

级联调用泛型函数时的泛型类型推断

使用无服务器工作流 go sdk 时出现间歇性 JSON 解组错误

为什么import和ImportSpec之间可以出现多行注释,而PackageName和ImportPath之间不能出现?

使用 delve 在容器中调试 Golang:container_linux.go:380:启动容器进程导致:exec:/dlv:stat /dlv:没有这样的文件或目录

从 Go struct 中提取标签作为 reflect.Value

我该如何做错误处理惯用的方式

为什么 Go 不允许将一个泛型分配给另一个泛型?

Go http标准库中的内存泄漏?