assemblyx86-64intel

x64 REX prefix for 16bit registers


I am confused about the REX prefix:

REX Bits:
|7|6|5|4|3|2|1|0|
|0|1|0|0|W|R|X|B|
W bit = Operand size 1==64-bits, 0 == legacy, depends on opcode.
R bit = Extends the ModR/M reg field to 4 bits. 0 selects rax-rsi, 1 selects r8-r15
X bit = extends SIB 'index' field, same as R but for the SIB byte (memory operand)
B bit = extends the ModR/M r/m or 'base' field or the SIB field.  

But:

$ echo 'mov %al, %al' | as -al -o /dev/null - | tail -1
   1 0000 88C0      mov %al,%al
$ echo 'mov %ax, %ax' | as -al -o /dev/null - | tail -1
   1 0000 6689C0    mov %ax,%ax
$ echo 'mov %eax, %eax' | as -al -o /dev/null - | tail -1
   1 0000 89C0      mov %eax,%eax
$ echo 'mov %rax, %rax' | as -al -o /dev/null - | tail -1
   1 0000 4889C0    mov %rax,%rax

Solution

  • 66h is the operand size override prefix. Basically, in 32- or 64-bit mode, it specifies that the instruction is to operate on 16-bit data and use 16-bit registers. (In 16-bit mode, it specifies that the instruction operates on 32-bit data.)

    So it is a prefix, but it's not a REX prefix. Indeed, it predates the whole REX prefix system; it has existed since the 386, the first 32-bit x86 CPU, whereas REX is specific to x86-64.