Cole Tobin
Cole Tobin

Reputation: 9429

Why can we use eRx in 16 bit mode, but not rRx in 32 bit mode?

In x86 assembly, why can we use eRx in 16 bit "real mode", but we can't use rRx in 32 bit mode? For example:

BITS 16
mov bx, 1
mov eax, 2

will assemble and disassemble correctly. And it works, as I have disassembled the Win2k bootloader before and found references to eax.

However, how come there is no way, even on a 64-bit processor, in 32-bit "protected mode", you can't access rRx?

Upvotes: 3

Views: 390

Answers (3)

Alexey Frunze
Alexey Frunze

Reputation: 62048

You can't access 64-bit registers in non-64-bit modes by design, CPU design.

You can access 32-bit registers in 16-bit modes by design as well. You do this by using the special instruction prefixes called operand size prefix (0x66) and address size prefix (0x67).

There are no special instruction prefixes to reach 64-bit registers in non-64-bit modes.

There was not enough opcode/prefix coding space left in 32-bit mode to add that in, unlike when 386 extended 286 there were some unused bytes for prefixes.

The 0x4? REX prefixes that are needed to specify 64-bit operand-size in 64-bit mode are inc/dec instructions in 32-bit and 16-bit mode. AMD64 had to change the meaning of some bytes to make room for the prefixes they wanted to. The same change to 32-bit mode would not be compatible with existing binaries.

Upvotes: 4

FrankH.
FrankH.

Reputation: 18217

The reason for this is that the 64bit mode changes instruction decoding in one particular place - namely, to enable the prefix bytes used to indicate operand sizes of 64bit / extend register width to 64bit / extend register usage to the "new" R8..R15 registers. These are different from the "alternate size prefix" (0x66), which is generic to x86 (independent of the CPU operating mode) and changes operand/register size from 16bit to 32bit if in 16bit mode, and vice versa from 32bit to 16bit if in 32bit mode.

The so-called REX prefixes are encoded as 0x40..0x4f and are only valid as prefixes if the CPU is operating in 64bit mode. Why is that so ? Well - as said, changed instruction decoding, these opcodes actually map to one-byte versions of inc <reg>/dec <reg> in classical x86.
This is possible because of an ambiguity in the 16/32bit instruction set - inc EAX can be either 0x40 or 0xff 0xc0. In 64bit mode, the instruction decoder only accepts 0xff 0xc0 for this. On the other hand, 0x40, as indicated, becomes one of the REX prefixes.

Hence - these 64bit operand size prefixes do not exist in 16bit/32bit mode (they are inc/dec operations then ...), therefore there exists no way for 16bit/32bit x86 code to state "I'd like to do a 64bit op".

As an example, here's the assembly / opcodes for a few instructions with different operand sizes:

      64bit   32bit option 1   32bit option 2     instruction
=============================================================
      fe c8            fe c8               --     dec    al
   66 ff c8         66 ff c8            66 48     dec    ax
      ff c8            ff c8               48     dec    eax
   48 ff c8               --               --     dec    rax

As you can see, 64bit knows no one-byte version of dec eax, but instead it knows 0x48 as (one of several) instruction prefix(es) saying "make this a 64bit op".

Upvotes: 7

Gunner
Gunner

Reputation: 5884

Well, if you were using a 80286, then it would not work! The computer you are using is a 32bit CPU which has both 16bit and 32bit registers but NOT 64bit registers. It would work on a 64bit cpu also.

Upvotes: 1

Related Questions