I've looked up Wikipedia for x86 backward compatibility in x86-x64 and it 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.
So I've tested some instructions to see that some are actually yield entirely different opcodes (rather than just applying prefix) such as: INC/DEC. Looking at (x86):
\x40 inc eax
\x48 dec eax
And while assembling the same in x86-x64 yields:
\xff \xc0 inc eax
\xff \xc8 dec eax
I'm trying to figure out the reason and more examples of other instructions that has the same symptoms that yield different opcodes. I am familiar with that push, pop, call, ret, enter and leave are not available 32 bit in x86-x64.
A 32-bit processor on x86 architecture has 32-bit registers, while 64-bit processors have 64-bit registers. Thus, x64 allows the CPU to store more data and access it faster. The register width also determines the amount of memory a computer can utilize.
states that the current x86-64 design “contains 981 unique mnemonics and a total of 3,684 instruction variants” [2].
What is the difference between x86 and x64? As you guys can already tell, the obvious difference will be the amount of bit of each operating system. x86 refers to a 32-bit CPU and operating system while x64 refers to a 64-bit CPU and operating system.
The x86 Windows versions can't run 64-bit applications. AMD64 and IA64 Windows will run ordinary 32-bit software, but not within the same process. Since 64-bit applications can't use 32-bit binaries, 64-bit versions of software applications won't be able to load 32-bit add-ons or components.
Almost all instructions that are available in both modes have the same opcodes in both modes.
Removed instructions:
CS
/DS
/ES
/SS
were removed. push/pop FS and GS are still valid (those two segments can still have a non-zero base in long mode). mov Sreg, r32
and mov r32, Sreg
are still available for the "neutered" segment registers, so you can emulate push / pop using a scratch integer reg. CS still matters; a far jump to another code segment can switch to 32-bit mode, and the others still need valid segment descriptors.Removed (repurposed) encodings of some still-available instructions: In your case, 32-bit can use the inc r32
single-byte opcodes (0x40 + register-number). 64-bit mode only has the inc r/m32
encoding, where the register to be incremented is specified with a 2nd byte. (In this case, the 0x4x bytes were repurposed as the REX prefix byte.)
Intel's insn reference (follow the link in the x86 tag wiki) shows the following for inc
:
Opcode Instruction Op/ 64-Bit Compat/
En Mode Leg mode
FF /0 INC r/m32 M Valid Valid Increment r/m doubleword by 1.
40+ rd INC r32 O N.E. Valid Increment doubleword register by 1.
N.E. means not encodable. The Op/En column describes how operands are encoded.
Jan Hubicka's AMD64 ISA overview briefly describes the repurposing of single-byte inc/dec opcodes for REX prefixes, and the default operand sizes and how immediate data is still 32-bit. movabs
is available for loading 64-bit immediate constants, or load/store from/to a 64-bit absolute address.
AMD's AMD64 manual, Section 2.5.11 Reassigned Opcodes has a table which is quite short. It only lists:
4x inc/dec r32
that turned into REX prefixes63 ARPL
that became MOVSXD
(sign-extend dword to qword, when used with REX.W=1 (which means the W bit in the REX prefix = 1)).Early AMD64 and Intel EM64T CPUs left out SAHF/LAHF
in long mode, but later re-added that instruction with the same opcode as in 32-bit. That table also doesn't list instructions that were removed entirely (the BCD instructions and maybe others) to make room for possible future extensions.
They could have simplified things a lot, and made x86-64 a much better cleaner instruction set with more room for future extensions, but every difference from 32-bit means more decoder transistors. There are no machine instructions that moved to a different opcode in 64-bit.
Multiple machine instructions often share the same asm mnemonic, mov
being the most overloaded one. There are loads, stores, mov with immediate-constants, move to/from segment registers, all in 8-bit and 32-bit. (16-bit is the 32-bit with an operand-size prefix, same for 64-bit with a REX prefix.) There's a special opcode for loading RAX from a 64-bit absolute address. There's also a special opcode for loading a 64-bit immediate-constant into a register. (AT&T syntax calls this movabs
, but it's still just mov
in Intel/NASM)
The statement is true, but somewhat misleading. The x86-64 architecture is backward compatible with x86, but the 32-bit instruction set is not compatible with the 64-bit instruction set.
You can run x86 code on a x86-64 CPU by using a compatibility mode. Actually, since the CPU should be transparently x86 to x86 code, it's the opposite : you enter 64-bit mode (long mode) when you want to run x86-64 code. This means you can't run both at the same time, though it is possible to switch from one mode to another.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With