32位应用程序可执行文件包含32位CPU的机器代码,但32位和64位Intel CPU的程序集和内部体系结构(寄存器数,寄存器宽度,调用约定)不同那么32位exe如何在64位机器上运行呢?
Wikipedia's x86-64 article says:
x86-64完全向后兼容16位和32位x86代码。 因为完整的x86 16位和32位指令集仍然在硬件中实现而没有任何干预仿真,现有的x86可执行文件运行时没有兼容性或性能损失,而现有的应用程序被重新编码以利用处理器设计的新功能可以实现性能提升。
我不明白他们的意思是说继续在硬件中实现而不进行任何干预仿真。这是什么意思?
答案 0 :(得分:6)
简短的回答是x86系列处理器都设计为向后兼容。在新CPU中执行算术和读/写操作的逻辑电路仍然能够执行为旧CPU设计的指令,同时还执行更新的指令,如64位加法和减法。
如果你想要更多历史......
x86指令集的历史可以追溯到20世纪70年代中期,从英特尔的第一个16位处理器8086开始。此CPU上的通用16位(2字节)寄存器称为AX
,BX
,CX
和DX
。 8086还允许访问每个寄存器的高字节和低字节。例如,您可以使用名称AX
访问AL
的低8位,或使用AH
访问高8位。
当英特尔开始开发具有新功能的新处理器时,他们希望它们向后兼容8086以及随后出现的任何处理器。接下来是80186,80286和80386--最后一个是他们的第一个32位处理器。
当然,80386上的所有寄存器必须是32位,但它也必须向后兼容旧的x86处理器。因此,英特尔只是将现有的扩展到EAX
,EBX
,ECX
,等等,而不是替换寄存器。 (E
含义"扩展")。 AX
寄存器只是EAX
寄存器的低16位,仍然可以访问。
英特尔的第一个64位处理器采用了相同的逻辑; 32位EAX
已扩展为64位RAX
,依此类推。当前的x86-64汇编语言仍然可以使用addl
,subl
,andl
,orl
等指令对32位寄存器执行算术运算, l
代表" long",即4字节/ 32位。 64位关节炎是使用addq
,subq
,andq
,orq
,...等完成的,其中q
代表"四字&# 34;,即8字节/ 64位。
编辑:This pdf看起来很好地介绍了32位和64位x86架构之间的差异。
答案 1 :(得分:2)
long mode不是仅扩展32位保护模式,而是64位内核在启动期间切换到的独立模式。在长模式下,CPU将从存储器读取的机器代码解码为x86-64指令。
兼容模式允许64位内核运行32位用户空间进程。这就是"没有仿真"手段。 CPU硬件直接在compat模式下读取和解码x86-32机器代码,就像机器在启动期间从未切换到64位模式一样。 (即64位手册称为传统模式)。
当在compat模式下运行的user-space进程中发生中断或系统调用时, CPU跳转到内核的中断或系统调用入口点时切换到长模式。这是" no emulation"的关键。声称:有硬件支持使32位进程使用与纯32位系统相同的机制与64位内核高效交互。
CPU可以使用大多数主要x86-64操作系统的大多数版本的默认安装都支持运行32位x86二进制文件(库和支持32位系统调用接口的内核)。即使在系统调用上,基本上也没有额外的开销。在Windows中,这称为WoW64(Windows64上的Windows)。
请注意,x86-64机器代码可能与16/32位机器代码完全不同。他们非常相似的主要原因是CPU可以在模式之间共享大部分指令解码硬件。
(当他们设计它时,AMD甚至不确定英特尔是否会采用AMD64,并且他们不想冒险在未来的CPU中使用大量晶体管用于AMD64指令解码硬件如果它没有流行起来的话。我怀疑这就是为什么他们如此保守地不清理尽可能多的x86传统行李。例如,丢弃更少使用的单字节指令以释放更短的编码空间更多有用的说明和未来的扩展。)
答案 2 :(得分:-1)
32位和64位程序之间的一个区别是用64位移动或计算的新指令。这些新指令使用32位程序中未使用的操作码或参数。较旧的指令使用与旧CPU相同的操作码实现,因此没有冲突*。
另一个区别是新的64位寻址模式。在内存中加载可执行文件时,操作系统将寻址模式设置为32位或64位。每当Windows在两个进程之间切换(一次多次发生),Windows就会更改用户模式应用程序的寻址模式。 Windows本身使用内核模式寻址模式。
*编辑:由于更改或删除了操作码,因此存在一些冲突。