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

时间:2019-05-17 12:07:04

标签: c 32bit-64bit

这个问题:How many bits does a WORD contain in 32/64 bit OS respectively?,提到字长是指处理器寄存器的位长-我指的是计算机处理器操作的位数,即最小的“不可分割”数量处理器运行的位。

对吗?使用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位字处理器的大小完全无关?

7 个答案:

答案 0 :(得分:28)

您参考的答案描述了64位对32位的优点。至于程序本身的实际区别,取决于您的观点。

通常来说,程序源代码不必完全相同。可以编写大多数程序,以便在适当选择编译器和/或编译器选项的控制下,它们可以像32位或64位程序一样完美地编译。然而,对源代码通常会产生一些影响,因为针对64位的(C)编译器可能会选择不同地定义其类型。特别是,long int在32位平台上普遍为32位宽,但在许多(但不是全部)64位平台上为64位宽。这可能是代码中的错误的来源,这些错误对此类详细信息做出了不必要的假设。

主要区别在于二进制文件。 64位程序利用其64位目标CPU的完整指令集,这些指令集总是包含32位对应CPU不包含的指令。他们将使用32位对应CPU没有的寄存器。他们将使用适合其目标CPU的函数调用约定,这通常意味着与32位程序相比,在寄存器中传递更多的参数。使用这些功能和其他64位CPU功能可提供一些功能优势,例如可以使用更多的内存和(有时)提高性能。

答案 1 :(得分:18)

单词大小是一个主要的区别,但这不是唯一的区别。它倾向于定义CPU被“评级”的位数,但是字长和整体功能只是松散相关。整体能力至关重要。

在Intel或AMD CPU上,32位与64位软件实际上是指CPU运行时所处的模式。 32位模式具有较少/较小的可用寄存器和指令,但是最重要的限制是可用的内存量。 32位软件通常只能使用2GB到不足4GB的内存

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

具有32位地址,程序可以寻址4GB(2 ^ 32字节),但是OS最多保留该空间的一半。可用的存储空间必须适合程序代码,数据,通常还可以容纳要访问的文件。在具有许多GB RAM的当今PC中,这无法利用可用内存。这就是6​​4位流行的主要原因。 64位CPU可用并被广泛使用(通常在32位模式下使用了几年),直到内存大小超过2GB成为普遍现象为止,此时64位模式开始提供实际优势,并开始流行。 64位的内存地址空间可提供16 EB的可寻址内存(约18兆字节),这是当前任何软件都无法使用的,并且肯定没有PC具有如此大的RAM。

即使在64位模式下,典型应用程序中使用的大多数数据也不需要是64位的,因此大多数数据仍以32位(或什至更小的)格式存储。文本的常见ASCII和UTF-8表示形式使用8位数据格式。如果程序需要将一大段文本从一个位置移动到内存中的另一个位置,则可以尝试一次将其进行64位处理,但是如果需要解释该文本,则可能一次要进行8位处理。类似地,32位是整数的通用大小(最大范围为+/- 2 ^ 31,或大约+/- 21亿)。 21亿美元足够用于多种用途。图形数据通常以像素为单位自然地表示,每个像素通常最多包含32位数据。

不必要地使用64位数据有一些缺点。 64位数据会占用更多的内存空间,并占用更多的CPU缓存空间(CPU使用的非常快的内存用于短期存储)。内存只能以最大速率传输数据,而64位数据则是其两倍。如果浪费使用,可能会降低性能。并且,如果有必要同时支持32位和64位版本的软件,则在可能的情况下使用32位值可以减少两个版本之间的差异并简化开发过程(尽管并非总是如此)。

在32位之前,地址和字长通常是不同的(例如,具有20位存储器地址但16位寄存器的16位8086/88,或具有16位存储器地址的8位6502,或者甚至早期的具有26位地址的32位ARM)。尽管没有程序员会为更好的寄存器而大吃一惊,但是存储空间通常是每一代技术发展的真正动力。这是因为大多数程序员很少直接使用寄存器,而是直接使用内存,并且内存限制直接导致程序员不愉快,在32位到64位的情况下,也给用户带来不愉快。

总而言之,尽管各种位大小之间存在着真实而重要的技术差异,但是32位或64位(或16位或8位)真正的含义往往与特定技术世代的CPU相关联的功能和/或利用这些功能的软件的集合。字长是其中的一部分,但不是唯一的,也不一定是最重要的部分。

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

答案 2 :(得分:11)

程序在由处理器实现的给定体系结构(架构或ISA)之上运行。通常,架构定义“主要”字长,即大多数寄存器的大小以及这些寄存器上运行的操作(尽管您可以设计工作原理不同的架构)。尽管架构可能允许使用大小不同的寄存器进行操作,但这通常被称为“本机”字长。

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

在整个历史中,有许多不同字长的架构,甚至是怪异的。如今,您可以轻松找到周围的处理器,这些处理器不仅是32位和64位,而且还包括8位和16位(通常在嵌入式设备中)。在典型的台式计算机中,您使用的是x86或x64,分别是32位和64位。

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

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

答案 3 :(得分:5)

  

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

这取决于所使用的CPU:

在SPARC CPU上,“ 32位”程序和“ 64位”程序之间的区别正是您所认为的:

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

对于x86 CPU,这是不同的:

现代x86 CPU具有不同的操作模式,并且可以执行不同类型的代码。在不同的模式下,他们可以执行16位,32位或64位代码。

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

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

mov    eax,0xbc614e
ret

...以32位代码和as:

mov    ax,0x614e
mov    sp,0xc300

...以16位代码显示。

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

  

64位程序将努力使指令集与64位字长对齐。

当CPU不是16位CPU时,16位代码(请参见上文)可以访问32位寄存器。

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

答案 4 :(得分:3)

  

提到字长是指处理器寄存器的位长

通常是(尽管有一些例外/并发症)

  
      
  • 我指的是计算机处理器操作的位数,即处理器操作的最小“不可分割”位数。
  •   

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

通常,在现代的32位和64位系统上,指针的大小与字长相同,尽管在许多64位系统上,并非实际上该指针的所有位都可用。可能有一种内存模型,其中可寻址内存大于系统本机字大小,这在8位和16位时代是很常见的,但是自从引入32位内存以来,它就不再受到青睐。位CPU。

  

由于计算机体系结构是固定的

尽管物理体系结构当然是固定的,但许多处理器具有多种操作模式,程序员可以使用不同的指令和寄存器。在64位模式下,可以使用CPU的全部功能;在32位模式下,处理器提供了向后兼容的接口,该接口限制了功能和地址空间。这些模式有很大的不同,因此必须为特定模式编译代码。

通常,以64位模式运行的OS可以支持以32位模式运行的应用程序,反之亦然。

因此,一个32位应用程序可以在运行32位OS的32位处理器,运行32位OS的64位处理器或运行64位OS的64位处理器上以32位模式运行位操作系统。

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

答案 5 :(得分:2)

您所拥有的信息是图片的重要部分,但并非全部。我不是处理器专家,所以可能有些细节会丢失我的答案。

32位和64位与处理器体系结构有关。单词大小的增加可以做一些事情:

  • 较大的字长可定义更多指令。例如,一个执行单个加载指令的8位处理器只能有256条指令,其中较大的字长允许在处理器微代码中定义更多的指令。显然,定义了多少个真正有用的指令是有限制的。
  • 由于有更多位可用,因此可以在一个指令周期内处理更多数据。这样可以加快执行速度。
  • 就像您所说的,它还允许访问更大的存储空间,而不必执行多个地址周期或多路复用高/低数据字之类的事情。

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

答案 6 :(得分:0)

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

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

那很简单,但是您可以在下面阅读更多内容。


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

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


32/64位CPU,第一个定义

CPU可以通过单个指令在内存中存储/调用一定数量的数据。一个32位CPU可以一次传输4个字节(32位),而一个64位CPU可以一次传输8个字节(64位)。因此,“ 32/64位”前缀来自单个读写周期中传输的RAM数量。

此数量会影响执行时间:所需的传输周期越少,CPU等待内存的次数就越少,程序执行速度就越快。就像用小桶或大桶盛满大量的水一样。

存储桶的大小(用于数据传输的位数)用于指示体系结构的效率,因此对于相同的CPU,32位应用程序的效率要低于64位应用程序。 / p>

32/64位CPU,技术定义

很明显,RAM和CPU必须都能够管理32/64位数据传输,这反过来又决定了用于将CPU连接到RAM(system bus)的电线数量。 32/64位实际上是组成数据总线(通常称为总线“宽度”)的导线/轨道的数量。

System Bus
(维基百科:System bus-数据总线宽度确定CPU,程序,OS等的前缀32/64位)

(另一条总线是地址总线,它通常更宽,但是在将CPU命名为32位或64位CPU时,地址总线宽度无关紧要。该地址总线宽度决定了CPU可以访问/“寻址”的RAM,例如2 GB或32 GB。对于控制总线,它是用于同步连接到数据总线的所有事物的小型总线。 ,它指示数据总线何时稳定并准备好在数据传输操作中进行采样。

当在CPU和RAM之间传输位时,在读取总线上的数据之前,数据总线的不同铜线上的电压必须稳定,否则一个或多个位的值将是错误的。稳定8位所需的时间少于64位,因此增加数据总线宽度并不是没有解决的问题。

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

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

二进制(本机汇编语言程序)是在考虑32位或64位体系结构以及相关指令集的情况下编写的。因此命名为32/64位程序。

目标体系结构的选择取决于将源程序转换为二进制文件时使用的编译器/编译器选项。大多数编译器能够从同一源程序生成32位或64位二进制文​​件。这就是为什么在下载首选程序或工具时会找到应用程序的两个版本的原因。

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

这也适用于操作系统本身,因为OS只是一组单独的程序和库。但是,操作系统本身就是用户程序的大型库,出于效率和安全性的考虑,它充当计算机硬件和用户程序之间的网关。编写OS的方式会阻止用户程序访问底层CPU体系结构的全部潜能。

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

由于64位CPU指令集是向后兼容的,因此64位操作系统能够在64位体系结构上运行32位二进制文​​件。但是,需要进行一些调整。

除了数据总线宽度和读/写指令子集外,32位和64位CPU之间还有许多其他差异(寄存器操作,内存缓存,数据对齐/边界,时序等)。

在64位体系结构上运行32位程序:

  • 比在较旧的32位体系结构上运行效率更高(几乎完全是由于与较旧的32/64位CPU相比,CPU时钟速度有所提高)
  • 效率不如运行同一应用程序(编译为64位二进制文​​件)以利用64位体系结构的效率低,特别是具有一次从内存到存储器的64位传输能力。

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

有关信息,不再完全支持编译为16位Windows二进制文件(在具有16位数据总线的80-286 CPU上运行的Windows的早期版本)的应用程序,尽管Windows 10上仍有可能激活NTVDM

.NET,Java和其他解释为“字节码”的情况

直到最近几年,编译器都被用来将源程序(例如C ++源代码)转换为机器语言程序,但是这种方法现在正在回归。

主要问题在于,某些CPU的机器语言与另一CPU的机器语言不同(请考虑使用ARM chip的智能手机与使用Intel chip的服务器之间的差异)。您绝对不能在两种硬件上都使用相同的二进制文件,它们使用的语言也不相同,即使可能,由于它们的工作方式存在巨大差异,两台计算机上的效率也不高。

当前的想法是使用从源头派生的指令的中间表示(IR)。 Java(Sun,现在不幸的是Oracle)和IL(Microsoft)就是这样的中间表示。可以在任何支持IR的操作系统上使用相同的IR文件。

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

但是,我们不能忘记实际的体系结构,因此即使没有针对特定体系结构优化应用程序本身(在IR级别上),也仍然有32 and 64 bit versions produced for the CoreCLR用于优化最终代码。下载并安装)。