Why in x64 some of the opcodes are invalid (06
, 07
for example), whereas in x86 are used for fairly basic instructions (06
and 07
being push
and pop
)? I thought that those simplest instructions would do nicely in both architectures.
Why they disabled some of those simple instructions in x64? Why wouldn't they work? Why they disabled some opcodes, creating holes in opcode list, when they could instead assign them to x64 versions of instructions?
Reference:
The 06
and 07
opcodes in 32-bit mode are the instructions PUSH ES
and POP ES
. In 64-bit mode, the segment registers CS, DS, ES, and SS are no longer used to determine memory addresses: the processor assumes a base address of 0 and no size limits. As there's now usually no reason for applications (other than the operating system itself) to access these registers, the push/pop opcodes for changing and accessing them were removed, leaving only mov
to/from Sreg (which is just 2 total opcodes; the register number goes in the ModRM byte instead of part of the 1-byte opcode). That's totally sufficient for something that's almost never needed.
The FS and GS segment registers can still set the base address in 64-bit mode, so push and pop opcodes related to them have not been removed. (These 2-byte 0F xx
opcodes were added in 386, and are a less valuable part of opcode space than the old 1-byte opcodes for 8086 segment registers).
Push/pop or mov
of segment registers is not how OSes would typically set FS or GS segment bases, though: that would require a GDT or LDT entry, and could only set a base within the low 32 bits. 64-bit OSes would use the associated MSRs to read and write the bases directly, not the architectural registers. (Modern 32-bit OSes do that, too, unless running on old hardware that doesn't support the segment base MSRs.)