面试官:说说 32 位和 64 位
在软件的世界里,有 32 位软件和 64 位软件,那么你是否想过 32 位和 64 位软件有什么区别吗?下面我就带领大家来看看 32 位和 64 位的区别。
第一个 64 位操作系统
首要的区别是 32 位和 64 位 CPU 的指令集合、操作数位数、寄存器名称和个数都不相同。例如 mov eax,1 指令,在 32 位 CPU 上对应的机器指令是 0x1201;而在 64 位机器上就变成了 0x123401。程序对于 CPU 而言,只是一系列顺序的在内存中的 01 代码。因为操作系统是直接运行在硬件上的,因此 32 位 CPU 只能运行 32 位操作系统。
这样的设计并没有什么问题,英特尔的 64 位架构的处理器就是这样设计的。但这里隐藏了一个问题,当我们需要升级硬件来提速,那么购买了新 CPU 后必须把部分运行在上面的操作系统或软件换掉。这个问题就是软硬件不兼容带,没有几个客户会去购买这种没法兼容原有软件环境的 CPU。因此 intel 和 amd 都推出了兼容 32 位软件环境的 CPU。所以现在主流 CPU 都是 64 位处理器,可以在上面运行 32 位和 64 位操作系统和软件。
一般来说编译器是一个应用软已,64 位电脑上的 64 位编译器编译出来的也就是 64 的软件。那么第一个 64 位操作系统是如何来的呢?首先操作系统大部分是用 C 语言编写的,编写完后经过编译器编译成可执行文件,那么这里就有一个问题:第一个 64 位操作系统是用 64 位编译器编译的,那么这个 64 位编译器是运行在 64 位操作系统上的,那么这个 64 位操作系统从哪来的?因此一定存在一个或一种编译器,本身是 32 位的,但能将程序编译成 64 位可执行文件。也只有在这种情况下编译器本身位数和编译出来程序的位数才不一致,也才能编译出第一个 64 位操作系统。
操作系统位数和软件位数关系
在讨论这个问题前,我们需要先明白软件是如何运行的?首先会寻找需要引入的内容(头文件),然后编译成目标文件(二进制文件),但是呢目标文件是没法运行的,因为里面有一定有未知符号没有解析。目标文件经过链接,就形成了可执行文件。为什么经过链接就可以形成可执行文件了呢?这是因为操作系统提供了编译好的动态链接库,因此我们只经过链接后就能云行了。这个过程有两个非常重要的地方,动态链接库和系统 API。
32 位操作系统上是没有 64 位库文件的,因此如果应用程序源代码中引用了 64 位动态库中才有的函数,那么链接的时候就会出问题。我们很多程序会用到库函数,库函数的实现是依赖于系统 API。例如在 windows 上程序大多数是以 exe 形式发布,exe 文件本身是带有位数的。再比如在 linux 上大部分软件包 rpm 是编译好的,它们本身就是具有“位数”,但是如果是源码,那么应用程序还没有“位数”这一概念,你用多少位的编译器去编译它,它就是多少位的应用程序。注意:我们这里讨论多少位的程序,都是针对已经编译到目标文件以后的状态。
看完前面的内容,请各位思考一下这两个问题:
64 位的系统上是否能运行 32 位应用程序;
32 位系统上是否能运行 64 位应用程序。
如果你的答案和下面的一致,就说明你理解了本篇文章:
对于操作系统来说 64 位系统上有 32 位库和其他信息,因此基本上兼容 32 位程序;
32 位操作系统一般是没有 64 位库。也没有相关系统 api。因此一般情况下 32 位系统没法运行 64 位应用程序。
评论