Almost all instructions that are available in both modes have the same opcodes in both modes.
Removed instructions:
- Binary-coded-decimal stuff like AAM (ASCII-adjust after multiplication) for fixing up binary-coded-decimal after doing normal binary add/sub/mul/div on a register holding two base-10 digits in each 4-bit half. They ran slowly anyway, and weren't used. Storing numbers as binary integers instead of BCD is widespread.
- push / pop of
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.
- Other obscure segment stuff like ARPL: Adjust RPL Field of Segment Selector. It's really just a bit-field clamp and set flags instructions for integer registers, so could be emulated by a few other instructions in the rare places where a kernel might want it.
- Maybe some other obscure or privileged instructions that compilers never used in 32-bit code. (Not that compilers ever emitted any of the above either, without intrinsics or inline asm.)
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 prefixes
63 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)
push/pop
are all encodable in amd64 (aka x86-64). The Intel insn set ref listspush r32
as not encodable in long mode, but actually you can, with a REX.W=0 prefix. (16 bit is encoded with an operand-size prefix for the usual opcode). Evenpush imm8
is available, but notpush r/m8
. You're right that call/ret and enter/leave always use 64bit operands / addresses in 64bit mode, though. – Rawalpindipush
/pop
is an illegal instruction in 64-bit mode. Only 16 and 64-bit push/pop are encodeable. – Rawalpindi