编辑:刚刚发现(感谢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中已经完成了专门用于此目的的模式。
答案 0 :(得分:2)
事实上,严格来说,程序是32位还是64位图像只能决定它的寻址模式,而不是它所使用的CPU功能,包括数据字大小(限制期望给定大小的API /库调用。)
不,这是不正确的。在Windows中,32位与64位是两个支持的英特尔架构和指令集的同义词。 (是的,还有其他架构支持--Alpha,Itanium,ARM - 但这些都是明确说明的。)
你所描述的二进制文件将是“x86_64架构,微小的内存模型”(简称通常称为x32
),其中微小的内存模型意味着指针小于系统字大小,以及数据和代码共享相同的地址空间。 People have made Linux systems like this
它与“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位代码。
答案 1 :(得分:2)
要使用x64功能,您需要以64位模式运行。您不能使用32位进程的64位寄存器。 32位进程仅限于32位x86操作码。您不能使用32位进程中的任何x64功能。