-2

编辑:刚刚发现(感谢 Ben Voigt 迅速指出)这个提议甚至是不可能的。对于后代来说,这是一个基本问题,而不是我之前对 AMD 扩展的误解:

我一直想知道 32 位构建(尤其是 Windows)软件是否常见检测 64 位处理器的存在并利用 64 位操作数和更大的寄存器文件(如果存在)。这是假设 32 位进程实际上可以使用 64 位指令,其方式与 i386 上的 16 位进程在物理上存在这样的 CPU 时可以使用 32 位指令的方式大致相同,通过编码覆盖前缀。但是,正如下面的答案所指出的那样,这是不可能的。

为什么要使用 64 位指令而不使用 32 位寻址?

好吧,假设您知道您正在处理的数据集足够小以适合该地址空间。例如,您使用了 64 位版本的程序,而对于您使用它的目的,性能监控会告诉您该进程正在使用 2GB 或更少。(实际上,根据this,设置了 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志的 32 位进程将在 64 位 Windows 中获得 4GB 用户空间。)

有些人会认为这无关紧要,但实际上,它可能。在 64 位版本中,如果我没记错的话,程序存储的每个指针都会消耗两倍的物理 RAM! 如果程序使用大量指针(例如,由于链表或哈希表),这可能会累加并降低缓存效率等。

不幸的是,正如下面 Ben Voigt 的回答所指出的,在 Windows 中根本不可能,而在 Linux 中已经完成了专门用于此目的的模式。

4

2 回答 2

3

事实上,严格来说,一个程序是 32 位还是 64 位图像只决定了它的寻址模式,而不是它使用的 CPU 特性,包括数据字大小(除非 API/库调用期望给定大小。)

不,这是不正确的。在 Windows 中,32 位与 64 位是两种受支持的英特尔架构和指令集的同义词。(是的,还支持其他架构——Alpha、Itanium、ARM——但这些总是明确说明的。)

像您描述的二进制文件将是“x86_64 架构,微型内存模型”(通常简称x32为),其中微型内存模型意味着指针小于系统字长,并且数据和代码共享相同的地址空间。 人们已经制作了这样的 Linux 系统

它与“32 位”x86 代码完全不兼容。x86 指令甚至没有额外寄存器的编码。CPU 的模式位必须设置不同以支持 x86_64 指令。它与 16 位内存模型时代存在的“基于寻址”和相对指针的概念非常相似。

x32 代码使用 x86_64 指令,并使用处理 32 位数据的指令来访问和执行指针计算。这是通过将虚拟地址限制在范围 (-2GB:+2GB) 的虚拟内存逻辑实现的,因此与将 32 位变量加载到 64 位寄存器相关联的正常符号扩展会创建有效的 64 位指针。

当 CPU 处于“长模式”以支持指令访问额外寄存器时,它无法正确解码 x86 指令。例如,0100 0000 在 x86 中是 ADD 指令,但在 x86_64 中是 MOV。

总之,在分配器的帮助下,64 位代码可以使用 32 位指针。不能将附加寄存器的使用混合到 32 位代码中。

于 2013-04-05T20:47:08.593 回答
2

为了使用 x64 功能,您需要在 64 位模式下运行。您不能在 32 位进程中使用 64 位寄存器。32 位进程仅限于 32 位 x86 操作码。您不能使用 32 位进程中的任何 x64 功能。

于 2013-04-05T20:54:09.727 回答