程序是 32 位还是 64 位意味着什么?

What does it mean for a program to be 32 or 64 bit?

这个问题:How many bits does a WORD contain in 32/64 bit OS respectively?,提到字长是指处理器寄存器的位大小——我认为这是指计算机处理器运行的位数/即最小的'indivisible' 处理器操作的位数。

对吗?使用像 Word/Excel/etc 这样的软件,安装程序可以选择 32 位或 64 位安装。有什么区别?

由于计算机体系结构是固定的,在我看来,“32 位”软件的设计应与具有 32 位体系结构的计算机体系结构保持一致。 64 位程序将努力使指令集与 64 位字长对齐。

对吗?

这里问了一个非常相似的问题:From a programming point of view, what does it mean when a program is 32 or 64 bit? - 接受的答案提到区别在于可以分配给应用程序的内存量。但这太模糊了——除非 32 位/64 位软件作为一个概念与 32 位/64 位字处理器大小完全无关?

您引用的答案描述了 64 位相对于 32 位的优势。至于程序本身到底有什么不同,这取决于您的观点。

一般来说,程序源代码完全不必不同。 Most programs can be written so that they compile perfectly well as either 32-bit or 64-bit programs, as controlled by appropriate choice of compiler and / or compiler options.通常 一些 对源代码有影响,但是,针对 64 位的 (C) 编译器可能会选择以不同方式定义其类型。特别是,long int 在 32 位平台上通常是 32 位宽,但在许多(但不是全部)64 位平台上它是 64 位宽。这可能是代码错误的来源,这些错误会对此类细节做出无根据的假设。

主要区别都在二进制文件中。 64 位程序使用其 64 位目标 CPUs 的完整指令集,其中总是包含 32 位对应 CPUs 不包含的指令。他们将使用 32 位副本 CPU 所没有的寄存器。他们将使用适合其目标 CPU 的 function-call 约定,这通常意味着在寄存器中传递比 32 位程序更多的参数。使用这些和 64 位 CPUs 的其他设施提供功能优势,例如能够使用更多内存和(有时)提高性能。

程序 运行 位于给定架构(arch 或 ISA)之上,由处理器实现。通常,架构定义 "main" 字大小,这是大多数寄存器和这些寄存器上的操作的大小 运行(尽管您可以设计工作方式不同的架构)。这通常称为 "native" 字长,尽管架构可能允许使用不同大小的寄存器进行操作。

此外,处理器使用内存,并且需要以某种方式寻址该内存——这意味着使用这些地址进行操作。因此,地址通常能够像任何其他数字一样存储和操作,这意味着您拥有能够保存它们的寄存器。尽管不要求这些寄存器与字长匹配,也不要求从单个寄存器计算出地址,但在某些体系结构中就是这种情况。

纵观历史,出现过许多不同字长的架构,甚至是怪异的架构。如今,您可以轻松找到身边的处理器,不仅有 32 位和 64 位的,还有例如8 位和 16 位(通常在嵌入式设备中)。在典型的桌面计算机中,您使用的是 x86 或 x64,分别是 32 位和 64 位。

因此,当您说程序是 32 位或 64 位时,您指的是特定的体系结构。在流行的桌面场景中,您指的是 x86 与 x64。有很多问题、文章和书籍讨论了两者之间的区别。

现在,最后一点:出于兼容性原因,x64 处理器可以在不同的模式下运行,其中一种模式能够 运行从 x86 编译 32 位代码。这意味着如果您的计算机是 x64(可能)并且您的操作系统支持它(也可能,例如 Windows 64 位),它仍然可以 运行 为 x86 编译的程序。

你所掌握的信息只是图片的一部分,但不是全部。我不是处理器专家,所以我的回答可能会遗漏一些细节。

32 位与 64 位与处理器架构有关。增加字数有几件事:

  • 更大的字长可以定义更多的指令。例如,执行单个加载指令的 8 位处理器总共只能有 256 条指令,其中较大的字大小允许在处理器中定义更多指令 micro-code。显然,定义多少真正有用的指令是有限制的。
  • 由于有更多位可用,因此单个指令周期可以处理更多数据。这加快了执行速度。
  • 如您所说,它还允许访问更大的内存 space,而无需执行多个地址周期或多路复用 high/low 数据字等操作。

当处理器架构从 32 位迁移到 64 位时,芯片制造商可能会保持与以前指令集的兼容性,因此以前开发的所有软件仍然 运行新架构。当您以 64 位架构为目标时,编译器将有新的可用指令和内存寻址方案,可以更有效地处理数据。

mentions that word size refers to the bit size of a processor register

一般是(虽然有一些exceptions/complications)

  • which I take to mean the number of bits that a computer processor operates on / i.e. the smallest 'indivisible' amount of bits that a processor operates on.

不,大多数处理器架构可以处理小于其本机字长的值。更好(但不完美)的定义是处理器可以作为单个单元处理(通过主整数数据路径)的最大数据块。

一般来说,在现代 32 位和 64 位系统上,指针的大小与字长相同,但在许多 64 位系统上,并非所述指针的所有位实际上都可用。有可能有一个内存模型,其中可寻址内存大于系统的本机字大小,并且在 8 位和 16 位时代这样做很常见,但自从引入 32-位 CPUs.

Since the computer architecture is fixed

虽然物理架构当然是固定的,但许多处理器具有多种操作模式,程序员可以使用不同的指令和寄存器。在 64 位模式下,CPU 的全部功能都可用,在 32 位模式下,处理器提供了一个向后兼容的接口,它限制了功能和地址 space。这些模式差异很大,必须针对特定模式编译代码。

作为一般规则,64 位模式下的 OS 运行 可以支持 32 位模式下的应用程序 运行 但不支持 vice-versa。

因此,32 位应用程序在 32 位处理器 运行 32 位 OS、64 位处理器 运行 上以 32 位模式运行32 位 OS 或 64 位处理器 运行 64 位 OS.

另一方面,64 位应用程序通常只能在 64 位处理器上运行 运行 64 位 OS。

Using software like Word/Excel/etc, the installers have the option for a 32bit or a 64bit installation. What is the difference?

这取决于使用的CPU:

在 SPARC CPUs 上,“32 位”和“64 位”程序的区别正是您所想的:

64 位程序使用 32 位 SPARC CPUs 不支持的额外操作。另一方面,Solaris 或 Linux 操作系统将 64 位程序访问的数据放在只能使用 64 位指令访问的内存区域中。这意味着 64 位程序甚至必须使用 32 位 CPUs 不支持的指令。

对于 x86 CPUs 这是不同的:

现代 x86 CPUs 有不同的操作模式,它们可以执行不同类型的代码。在不同的模式下,它们可以执行 16 位、32 位或 64 位代码。

在 16、32 和 64 位代码中,CPU 对字节的解释不同:

字节(十六进制)b8 4e 61 bc 00 c3 将被解释为:

mov    eax,0xbc614e
ret

... 在 32 位代码中为:

mov    ax,0x614e
mov    sp,0xc300

...在 16 位代码中。

“64 位安装”和“32 位安装”的 EXE 文件中的字节必须由 CPU 解释不同。

And a 64 bit program would make efforts to align instruction sets with 64 bit word sizes.

当 CPU 不是 16 位 CPU.

时,16 位代码(见上文)可以访问 32 位寄存器

因此“16 位程序”可以访问 32 位或 64 位 x86 上的 32 位寄存器CPU。

字长是一个主要区别,但不是唯一的区别。它倾向于定义 CPU 是 "rated" 的位数,但字长和整体能力只是松散相关。综合能力才是最重要的。

在 Intel 或 AMD CPU 上,32 位与 64 位软件实际上是指 CPU 在 运行 时运行的模式。 32 位模式有 fewer/smaller 个可用的寄存器和指令,但最重要的限制是可用内存量。 32 位软件通常仅限于使用 2GB 和略低于 4GB 的内存

内存的每个字节都有一个唯一的地址,这与每个房子都有一个唯一的邮政地址没有太大区别。内存地址只是一个数字,程序一旦将数据保存在内存中就可以使用它来再次查找数据,内存的每个字节都必须有一个地址。如果地址是 32 位,则有 2^32 个可能的地址,这意味着 2^32 个可寻址的内存字节。在今天的 Intel/AMD CPU 年代,内存地址的大小与寄存器的大小相同(尽管并非总是如此)。

对于 32 位地址,程序可以寻址 4GB(2^32 字节),但是 space 的一半被 OS 保留。可用内存 space 必须适合程序代码、数据,通常还有正在访问的文件。在今天的 PC 中,有许多 GB 的 RAM,这无法利用可用内存。这就是 64 位变得流行的主要原因。 64 位 CPU 可用并广泛使用(通常在 32 位模式下)已有几年,直到大于 2GB 的内存变得普遍,此时 64 位模式开始提供 real-world优点而流行起来。 64 位内存地址 space 提供 16 艾字节的可寻址内存(约 18 quintillion 字节),这超过了当前任何软件可以使用的容量,当然没有 PC 有接近那么多的 RAM。

即使在 64 位模式下,典型应用程序中使用的大部分数据也不需要是 64 位的,因此大部分数据仍以 32 位(甚至更小)格式存储。文本的常见 ASCII 和 UTF-8 表示使用 8 位数据格式。如果程序需要在内存中将一大块文本从一个地方移动到另一个地方,它可能会尝试一次 64 位,但如果它需要解释文本,它可能会一次 8 位.类似地,32 位是整数的常见大小(最大范围为 +/- 2^31,或大约 +/- 21 亿)。 21 亿对于许多用途来说已经足够了。图形数据通常是逐像素自然表示的,每个像素通常最多包含 32 位数据。

不必要地使用 64 位数据有一些缺点。 64 位数据在内存中占用更多 space,在 CPU 缓存中占用更多 space(CPU 用于 short-term 存储的非常快的内存) .内存只能以最大速率传输数据,而 64 位数据是其两倍大。如果浪费使用,这会降低性能。如果需要同时支持 32 位和 64 位版本的软件,则尽可能使用 32 位值可以减少两个版本之间的差异并使开发更容易(但并不总是这样)。

在 32 位之前,地址和字长通常不同(例如 16 位 8086/88 具有 20 位内存地址但 16 位寄存器,或 8 位 6502 具有 16 位内存地址,甚至早期的 32 位 ARM 和 26 位地址)。虽然没有程序员会对更好的寄存器嗤之以鼻,但内存 space 通常是每一代技术进步的真正驱动力。这是因为大多数程序员很少直接和寄存器打交道,而是直接和内存打交道,而内存的限制直接给程序员带来不愉快,32位到64位的情况下,用户也是如此。

总而言之,虽然各种位大小之间存在真正且重要的技术差异,但 32 位或 64 位(或 16 位或 8 位)真正意味着什么 只是能力的集合,往往与特定技术世代的 CPU 相关联,and/or 软件利用这些能力。字长是其中的一部分,但不是唯一的,也不一定是最重要的部分。

资料来源:在所有这些技术时代都是程序员。

简短回答:这是一个仅基于底层数据总线宽度的约定

n-bit 程序是针对 n-bit CPU 优化 的程序。换句话说,64 位程序 是 64 位 CPU 的二进制程序 compiled。 64 位 CPU 反过来, 是利用 64 位数据总线 在 CPU 和内存之间交换数据。

就这么简单,但您可以在下面阅读更多内容。


该定义实际上重定向到了解什么是 32/64 位 CPU,间接地了解什么是 32/64 位操作系统,以及编译器如何针对给定体系结构优化二进制文件。

优化 这里包含二进制文件本身的格式。给定 OS 的 32 位和 64 位二进制文​​件,例如一个 Windows 二进制文件,有不同的格式。但是,给定的 64 位 OS,例如Windows64、将能够读取和启动为32位版本和32位宽数据总线编写的32位二进制文​​件。


32/64位CPU,先定义

CPU 可以store/recall 一条单条 指令在内存中存储一​​定数量的数据。 32位的CPU可以一次传输4个字节(32位),64位的CPU可以一次传输8个字节(64位)。因此,“32/64 位”前缀来自单个 read/write 周期内传输的 RAM 数量。

这个数量影响执行时间:需要的传输周期越少,CPU等待内存的时间越少,程序执行得越快。这就像用一个小桶或一个大桶来装大量的水。

桶的大小(用于数据传输的位数)用于指示架构的效率,因此对于相同的 CPU,32 位应用程序的效率低于64 位应用程序。

32/64位CPU,技术定义

显然,RAM 和 CPU 都必须能够管理 32/64 位数据传输,这反过来又决定了用于将 CPU 连接到内存(system bus)。 32/64位其实就是wires/tracks的个数组成了数据总线(通常命名为总线"width")


(维基百科:System bus - 数据总线宽度决定了 CPU、程序、OS、...的前缀 32/64 位)

(另一种总线是地址总线,它通常更宽,但地址总线宽度与将CPU命名为32位或64位无关CPU。这个地址总线宽度决定了CPU可以达到/"addressed"的RAM总量,例如2GB或32GB。至于控制总线,它是一个小总线,用于同步所有连接到数据总线的东西,特别是,它指示数据总线何时稳定并准备好在数据传输操作中进行采样。

当CPU和RAM之间传输位时,数据总线不同铜轨上的电压必须稳定才能读取总线上的数据,否则一个或多个位值将被错误的。稳定8位比稳定64位花费的时间更少,所以增加数据总线宽度也不是没有问题要解决。

32/64 位程序:编译器问题

程序并不总是需要传输4字节(32位数据总线)或8字节(64位数据总线),所以它们使用不同的指令来读取1字节、2字节、4字节和8 位,出于性能原因。

二进制文件(本机汇编语言程序)是根据 32 位体系结构或 64 位体系结构以及相关指令集编写的。所以名称为 32/64 位程序。

目标体系结构的选择是 compiler/compiler 将源程序转换为二进制文件时使用的选项的问题。大多数编译器都能够从同一个源程序生成 32 位或 64 位二进制文​​件。这就是为什么您在下载您喜欢的程序或工具时会发现一个应用程序的两个版本。

但是,大多数程序都依赖于其他程序员编写的 ready-made 库(例如,视频编辑程序可能会使用 FFmpeg 库)。要生成完全 64 位的应用程序,编译器(实际上是 link 编辑器,但让我们保持简单)需要访问所使用的任何库的 64 位版本,这可能是不可能的。

这也适用于操作系统本身,因为 OS 只是一套独立的程序和库。但是,出于效率和安全原因,OS 本身就是一种用户程序的大库,充当计算机硬件和用户程序之间的网关。 OS 的编写方式会阻止用户程序访问底层 CPU 架构的全部潜力。

32 位程序与 64 位程序的兼容性 CPU

64 位操作系统能够 运行 64 位架构上的 32 位二进制文​​件,因为 64 位 CPU 指令集是 retro-compatible。但是,需要进行一些调整。

除了数据总线宽度和 read/write 指令子集之外,32 位和 64 位之间还有许多其他差异 CPU(寄存器操作、内存缓存、数据 alignment/boundaries , 计时, ...).

运行 64 位架构上的 32 位程序:

  • 比 运行 在旧的 32 位架构上更有效(几乎完全是由于 CPU 与旧的 32/64 位 CPU 代相比时钟速度提高)
  • 效率低于 运行将同一应用程序编译成 64 位二进制文​​件以利用 64 位架构,特别是一次传输 64 位的能力 from/to记忆.

    将源代码编译成 32 位二进制文​​件时,编译器仍将使用小桶,而不是 64 位数据总线可用的较大桶。与编译为使用大桶的相同应用程序相比,这对执行速度的影响最大。

有关信息,将应用程序编译成 16 位 Windows 二进制文件(Windows 运行ning 的早期版本 80-286 CPU with a 16-bit data bus) are not fully supported anymore, though there is still a possibility on Windows 10 to activate NTVDM

.NET的情况,Java等解释"byte-code"

虽然直到最近几年,编译器才被用来将源程序(例如 C++ 源代码)翻译成机器语言程序,但这种方法现在正在回归。

主要问题是某些 CPU 的机器语言与其他机器语言不同(想想使用 ARM chip and a server using an Intel chip 的智能手机之间的差异)。您绝对不能在两种硬件上使用相同的二进制文件,它们使用的不是同一种语言,即使可能,由于它们工作方式的巨大差异,两台机器上的效率也会很低。

当前的想法是使用从源代码派生的指令的中间表示 (IR)。 Java(Sun,遗憾的是现在是 Oracle)和 IL(Microsoft)就是这样的中间表示。相同的 IR 文件可用于任何支持 IR 的 OS。

一旦 OS 打开文件,它会最终编译成实际 CPU 理解的 "local" 机器语言,并考虑到 CPU 的最终架构 运行 程序。例如,对于 Microsoft .NET,通用版本由位于最终计算机上的 CoreCLR 虚拟机执行。在这种中间语言中通常没有数据总线宽度的概念,因此越来越少的应用程序会有这个 n-bit 前缀。

但是我们不能忘记实际的架构,所以仍然会有 32 and 64 bit versions produced for the CoreCLR 来优化最终代码,即使应用程序本身在 IR 级别没有针对给定的架构进行优化(只有一个红外版下载安装)。