Assembly: why some x86 opcodes are invalid in x64?

北战南征 提交于 2020-07-20 10:14:05

问题


My question arises from a simple curiosity:

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 though 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:

http://ref.x86asm.net/coder32.html

http://ref.x86asm.net/coder64.html


回答1:


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 now usually no reason for applications (other than the operating system itself) to access these registers, the opcodes for changing and accessing them were removed.

The FS and GS segment registers can still set the base address in 64-bit mode, so the opcodes related to them have not been removed.




回答2:


For all CPUs there's something like an "opcode space". For example, if a CPU used 8-bit opcodes then there'd be a max. of 256 instructions it could have. The larger opcodes are the more opcodes you can have, but the harder it is to fetch and decode them quickly.

80x86 is a relatively old architecture. It started out with a modest opcode space consisting of mostly 1-byte and 2-byte opcodes. Each time CPU manufacturers add a new feature it takes more opcodes from the opcode space. They ran out of opcodes. They ran out quickly.

To work around it they started doing things like adding escape codes and prefixes to artificially extended the opcode space. For an example, for recent AVX instructions you're looking at a VEX prefix followed by an old/recycled escape code (e.g. 0xF0), followed by an old/recycled address/operand size prefix (e.g. 0x66), followed by another 4 bytes. It's not pretty.

At the same time there's old instructions that are rarely used now (AAD, AAM, etc) and instructions with multiple/redundant opcodes (INC/DEC) that were consuming valuable "1-byte" opcodes. These couldn't/can't be removed entirely due to backward compatibility.

However; when 64-bit was being designed there simply wasn't any 64-bit code to be compatible with - backward compatibility didn't matter. The 1-byte opcodes being consumed by "not very important" instructions could be recycled; making those instructions invalid in 64-bit code (but freeing up some of the valuable 1-byte opcodes).

Most of those 1-byte opcodes (the entire 1-byte INC/DEC group if I remember right) got recycled immediately for the REX prefix that was needed to support 64-bit operands. Some weren't and became "free for future extensions" (with the restriction that the extension can only work in 64-bit code because those instructions are still valid in 16-bit and 32-bit code).



来源:https://stackoverflow.com/questions/30938318/assembly-why-some-x86-opcodes-are-invalid-in-x64

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