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.
0100
;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
0x66
a REX prefix on %ax
? Is there another name for that byte?0x66
is 0110 0110
, so it does not match the starts with the 0100
rule to be a REX.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.