如何确定体系结构上字的大小(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 例如,当您执行从intint32 的转换时,检测字的大小是相关的。在 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 &gt;&gt; n 需要将int 类型的x 归零?还是编译时 eval 有什么特别之处,所以它可以工作,但变量计数移位可以在没有额外检查的情况下编译? 好吧,显然 Go 中的可变计数移位确实必须在以 x86-64 为目标时进行编译检查,以保留 Go 语义,即为大计数移出所有位:godbolt.org/z/sWfjcnWoW。实际上也是 ARM64,因为它只饱和低 8 位,而不是全部。所以,是的,如果您的语言定义了这种行为,请利用它。相反,您可以比较 ^uint(0) == 0xFFFFFFFF 或类似的东西,至少对我来说这似乎更简单、更“明显”,但我不知道 Go。 @PeterCordes 有趣!感谢您的洞察力。

以上是关于如何确定体系结构上字的大小(32 或 64)?的主要内容,如果未能解决你的问题,请参考以下文章

在 64 位机器上 QWORD 的大小是多少?

ARMV8 datasheet学习笔记4:AArch64系统级体系结构之VMSA

获取 Windows 体系结构(32/64 位版本)

如何在 Python 中确定“单词”的大小

64 位计算机如何处理长整数?如何确定对象的大小? [关闭]

32 位和 64 位 ODBC 驱动程序之间的体系结构不匹配