Windows 32位软件版本通常是64位优化的吗?

Windows 32位软件版本通常是64位优化的吗?,windows,64-bit,32bit-64bit,Windows,64 Bit,32bit 64bit,编辑:刚刚发现(感谢Ben Voigt快速指出)这个提议根本不可能。对于子孙后代来说,这是一个基本问题,而不是我之前对AMD扩展的误解: 我一直在想,32位版本(特别是Windows)软件检测是否存在64位处理器并使用64位操作数和较大的寄存器文件(如果存在)是否很常见。这是假设32位进程实际上可以利用64位指令,其方式与i386上的16位进程利用32位指令的方式大致相同,当这样的CPU实际存在时,通过编码覆盖前缀。然而,正如下面的答案所指出的,这是不可能的 为什么要使用64位指令而不是32位寻

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

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

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

好吧,假设您知道您正在处理的数据集很小,足以容纳该地址空间。例如,您使用了64位版本的程序,对于您使用它的目的,性能监视会告诉您该进程使用的是2GB或更少。(实际上,根据我们的研究,设置了IMAGE\u FILE\u LARGE\u ADDRESS\u AWARE标志的32位进程在64位窗口中可以获得4GB的用户空间。)

有些人会认为这不重要,但事实上,可能会。在64位构建中,如果我没有弄错的话,程序存储的每个指针将消耗两倍于它需要的物理RAM!如果程序使用大量指针(例如,由于链表或哈希表),这可能会增加并降低缓存效率,等等

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

事实上,严格来说,一个程序是32位还是64位映像只决定它的寻址模式,而不决定它使用什么CPU功能,包括数据字大小(不包括预期给定大小的API/库调用)

不,这是错误的。在Windows中,32位与64位是两种受支持的英特尔体系结构和指令集的同义词。(是的,还支持其他体系结构——Alpha、安腾、ARM——但这些体系结构都是明确规定的。)

您描述的二进制文件是“x86_64体系结构,微型内存模型”(通常简称
x32
),其中微型内存模型意味着指针小于系统字大小,数据和代码共享相同的地址空间

它与“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位代码中。

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

32位构建的全部要点是使其能够在32位机器上运行。在32b机器上,您可以寻址4GB RAM,比目前市场上可用的内存要少得多,即使是笔记本电脑4GB也不多了。所以你的指针例子是完全没有意义的(双关语的意思)为什么这个被否决了,没有评论为什么?我也可能错了,但我觉得这是一个很好的问题,即使OP认为这是一个正确的问题,不是吗?@Sten是的,RAM很便宜,但是如果一个进程使用大量的64位指针,而32位指针可以做到,这仍然是低效的,并且可能会通过增加缓存未命中率影响性能。这对于计算密集型过程(如光线跟踪器)可能非常重要,因为在光线跟踪器中,CPU缓存大小仍然是一个材料限制。(@adam谢谢!)@Kevin如果代码如此关键,为什么不在汇编中编写它并编译64位-这样,如果你想部分正确,部分错误,你就可以拥有一个8位指针。x64指令仅在“长模式”下可用。但是然而,Windows并没有选择支持这一点。@ben yes,就我而言,sloppy,thanksOk,使用i386,在16位TSS中,操作数自动为8位或16位,或在32位TSS中为8位或32位-但是,您可以在指令上附加前缀,将编码改为在8位或32位操作数之间切换。如果我没有弄错的话,x86-64体系结构没有任何等效的方法来覆盖进程“mode-correct?”所暗示的操作数大小@Kevin:x86_64具有针对许多不同操作数大小的指令。但是你不能把x86_64编码的指令混合到x86代码中,你需要将处理器置于长模式。只要翻开AMD64体系结构程序员手册,我就知道你现在在说什么了。即使在长模式下的兼容模式下,前缀也不适用于64位操作数。每天学点东西!感谢您的快速回复,我感谢您的澄清。
0100 0000
是x8中的REX前缀