Why do 32-bit applications work on 64-bit x86 CPUs?

我怕爱的太早我们不能终老 提交于 2019-12-19 21:44:39

问题


32-bit application executables contain machine code for a 32-bit CPU, but the assembly and internal architecture (number of registers, register width, calling convention) of 32-bit and 64-bit Intel CPU's differ, so how can a 32-bit exe run on a 64-bit machine?

Wikipedia's x86-64 article says:

x86-64 is fully backwards compatible with 16-bit and 32-bit x86 code. Because the full x86 16-bit and 32-bit instruction sets remain implemented in hardware without any intervening emulation, existing x86 executables run with no compatibility or performance penalties, whereas existing applications that are recoded to take advantage of new features of the processor design may achieve performance improvements.

I don't understand what they mean by saying remain implemented in hardware without any intervening emulation. What does it mean?


回答1:


The short answer is that the x86 family of processors were all designed to be backward compatible. The logic circuits that perform arithmetic and read/write operations in new CPUs are still capable of carrying out instructions designed for older CPUs while also carrying out newer instructions like 64-bit add and subtract.


If you want more history...

The x86 instruction set dates back to the mid-1970s, beginning with Intel's first 16-bit processor, the 8086. The general-purpose 16-bit (2-byte) registers on this CPU were called AX, BX, CX, and DX. The 8086 also allowed access to the high and low bytes of each register. For example, you could access the lower 8 bits of AX using the name AL, or the higher 8 bits using AH.

When Intel started developing new processors with new features, they wanted them to be backward compatible with the 8086 and any processors that came afterward. Next in line came the 80186, the 80286, and the 80386--the last of which was their first 32-bit processor.

Of course, all the registers on the 80386 had to be 32-bit, but it also had to be backward compatible with older x86 processors. So rather than replace the registers, Intel merely extended the existing ones to EAX, EBX, ECX, ...etc. (E meaning "extended"). The AX register is merely the lower 16 bits of theEAXregister, and is still accessible.

The same logic was followed with Intel's first 64-bit processor; the 32-bit EAX was extended to the 64-bit RAX and so on. The current x86-64 assembly language can still perform arithmetic operations on 32-bit registers using instructions like addl, subl, andl, orl, ... etc, with the l standing for "long", which is 4 bytes/32 bits. 64-bit arthimetic is done with addq, subq, andq, orq, ...etc, with q standing for "quadword", which is 8 bytes/64 bits.

EDIT: This pdf looks like it gives a good introduction to the differences between 32-bit and 64-bit x86 architectures.




回答2:


Instead of just extending 32-bit Protected mode, long mode is a separate mode that 64-bit kernels switch to during bootup. When in long mode, the CPU decodes machine-code read from memory as x86-64 instructions.

There's a Compatibility Mode that lets a 64-bit kernel run 32-bit user-space processes. This is what "no emulation" means. The CPU hardware directly reads and decodes x86-32 machine code in compat mode the same way it would if the machine had never switched to 64-bit mode at all during bootup. (i.e. what the 64-bit manuals call legacy mode).

When an interrupt or system call happens in a user-space process running in compat mode, the CPU switches to long mode while jumping to the kernel's interrupt or system-call entry point. This is the key to the "no emulation" claim: there's hardware support for having 32-bit processes efficiently interact with a 64-bit kernel using the same mechanisms as on a purely 32-bit system.

Wikipedia has a table of modes the CPU can be in.

Default installs of most versions of most major x86-64 OSes come with support for running 32-bit x86 binaries (libraries, and a kernel that supports the 32-bit system call interfaces). There's basically no extra overhead even on system calls. In Windows, this is called WoW64 (Windows on Windows64).


Note that x86-64 machine code could have been designed to be totally different from 16/32-bit machine code. The main reason they're extremely similar is so the CPU can share most of the instruction-decoding hardware between modes.

(When they designed it, AMD wasn't even sure that Intel would ever adopt AMD64, and they didn't want to risk being stuck using a lot of transistors for AMD64 instruction-decode hardware in future CPUs if it didn't catch on. I suspect this is why they were so conservative about not cleaning up as much x86 legacy baggage as they could have. e.g. dropping more less-used one-byte instructions to free up space for shorter encodings for more-useful instructions, and future extensions.)




回答3:


One difference between 32-bit and 64-bit programs are the new instructions for moving or calculating with 64 bits. Those new instructions uses opcodes or arguments that weren't used in 32-bit programs. The older instructions are implemented with the same opcode they were implemented in older CPUs, so there isn't conflict*.

The other difference is the new 64-bit addressing mode. While loading an executable in memory, the OS sets the addressing mode to 32-bit or 64-bit. Everytime Windows switches between two processes (which happens many times in a second), Windows changes the addressing mode for the usermode applications. Windows itself uses the kernelmode addressing mode.

*EDIT: There are some conflicts due to changed or removed opcodes.



来源:https://stackoverflow.com/questions/28307180/why-do-32-bit-applications-work-on-64-bit-x86-cpus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!