如何确定体系结构上字的大小(32 或 64)?
Posted
技术标签:
【中文标题】如何确定体系结构上字的大小(32 或 64)?【英文标题】:How can I determine the size of words in bits (32 or 64) on the architecture? 【发布时间】:2021-11-25 10:28:41 【问题描述】:我不是在寻找runtime.GOARCH
,因为它提供了已编译程序的拱门。我想检测操作系统架构,假设我在 64 位机器上运行 32 位 go
程序,我需要将其识别为 64 而不是 32 位。
【问题讨论】:
你可以看看int
的大小。它是特定于架构的。
由于架构是 32 位或 64 位,您可以将 goarchList 映射到 32 位或 64 位。并使用runtime.GOARCH
返回的值作为键。 playground example.
你为什么想知道这个?唯一重要的方法是检测您的 32 位程序是否在 64 位架构上运行。或者,如果您想为其他程序创建安装程序/启动器。您已经知道程序的位数,并且 64 位应用程序无法在 32 位机器上运行。
@PanagiotisKanavos 例如,当您执行从int
到int32
的转换时,检测字的大小是相关的。在 64 位架构上,您可能会丢失信息。
下面的答案能回答你的问题吗?如果是,请接受。如果没有,请说明缺少的内容。
【参考方案1】:
借助一些位移 foo,您可以通过定义适当的常量(下面称为 BitsPerWord
)来确定 int
/uint
/uintptr
的大小。作为一个 Go 常量,它当然是在编译时而不是在运行时计算的。
这个技巧是used in the math
package,但没有导出有问题的常量 (intSize
)。
package main
import "fmt"
const BitsPerWord = 32 << (^uint(0) >> 63)
func main()
fmt.Println(BitsPerWord)
(Playground)
说明
^uint(0)
是设置所有位的 uint
值。
将第一步的结果右移 63 位得到
0
在 32 位架构上,并且
1
在 64 位架构上。
-
将
32
左移与第二步产生的结果一样多的位置
32
在 32 位架构上,并且
64
在 64 位架构上。
【讨论】:
有趣。在 C 中这是无效的;将整数移位超过类型的位宽不是很好定义的。我假设 Go 确实在此处定义了行为,因此对于任何大于或等于 32 的n
,32 位机器上的x >> n
需要将int
类型的x
归零?还是编译时 eval 有什么特别之处,所以它可以工作,但变量计数移位可以在没有额外检查的情况下编译?
好吧,显然 Go 中的可变计数移位确实必须在以 x86-64 为目标时进行编译检查,以保留 Go 语义,即为大计数移出所有位:godbolt.org/z/sWfjcnWoW。实际上也是 ARM64,因为它只饱和低 8 位,而不是全部。所以,是的,如果您的语言定义了这种行为,请利用它。相反,您可以比较 ^uint(0) == 0xFFFFFFFF
或类似的东西,至少对我来说这似乎更简单、更“明显”,但我不知道 Go。
@PeterCordes 有趣!感谢您的洞察力。以上是关于如何确定体系结构上字的大小(32 或 64)?的主要内容,如果未能解决你的问题,请参考以下文章
ARMV8 datasheet学习笔记4:AArch64系统级体系结构之VMSA