tabelas do prefixo REX

This commit is contained in:
Blau Araujo 2025-07-01 23:26:27 -03:00
parent c16e8e9261
commit a2bdba6e1f

87
docs/prefixo-rex.org Normal file
View file

@ -0,0 +1,87 @@
* Prefixos REX na arquitetura Intel 64 (x86-64)
O prefixo REX é um byte opcional usado no modo 64 bits para:
- Acessar registradores estendidos (~r8r15~)
- Usar operandos de ~64~ bits
- Estender campos ~ModR/M~, ~SIB~ ou ~opcode~
** Formato geral do prefixo REX (1 byte)
#+begin_example
Bits: 7 6 5 4 | 3 | 2 | 1 | 0
0 1 0 0 W R X B
#+end_example
| Bit | Nome | Função |
|-----+------+--------------------------------------------------------------------|
| ~74~ | ~0100~ | Identifica o byte como prefixo REX |
| ~3~ | ~W~ | ~1~ = operandos de ~64~ bits |
| ~2~ | ~R~ | Estende o campo ~Reg~ no byte ~ModR/M~ |
| ~1~ | ~X~ | Estende o campo ~Index~ no byte ~SIB~ |
| ~0~ | ~B~ | Estende o campo ~Base~ no ~ModR/M~, ~SIB~ ou campo ~reg~ em certos opcodes |
** Tabela dos 16 prefixos REX possíveis (~0x400x4F~)
| Hex | Binário | ~W~ | ~R~ | ~X~ | ~B~ | Significado resumido |
|------+----------+---+---+---+---+-------------------------------------------------|
| ~0x40~ | ~01000000~ | ~0~ | ~0~ | ~0~ | ~0~ | Sem extensão nem ~64~-bit |
| ~0x41~ | ~01000001~ | ~0~ | ~0~ | ~0~ | ~1~ | ~B = 1~ (extensão do campo Base) |
| ~0x42~ | ~01000010~ | ~0~ | ~0~ | ~1~ | ~0~ | ~X = 1~ (extensão do campo Index) |
| ~0x43~ | ~01000011~ | ~0~ | ~0~ | ~1~ | ~1~ | ~X = 1~, ~B = 1~ |
| ~0x44~ | ~01000100~ | ~0~ | ~1~ | ~0~ | ~0~ | ~R = 1~ (extensão do campo Reg) |
| ~0x45~ | ~01000101~ | ~0~ | ~1~ | ~0~ | ~1~ | ~R = 1~, ~B = 1~ |
| ~0x46~ | ~01000110~ | ~0~ | ~1~ | ~1~ | ~0~ | ~R = 1~, ~X = 1~ |
| ~0x47~ | ~01000111~ | ~0~ | ~1~ | ~1~ | ~1~ | ~R = 1~, ~X = 1~, ~B = 1~ |
| ~0x48~ | ~01001000~ | ~1~ | ~0~ | ~0~ | ~0~ | ~W = 1~ (operandos de ~64~ bits) |
| ~0x49~ | ~01001001~ | ~1~ | ~0~ | ~0~ | ~1~ | ~W = 1~, ~B = 1~ |
| ~0x4A~ | ~01001010~ | ~1~ | ~0~ | ~1~ | ~0~ | ~W = 1~, ~X = 1~ |
| ~0x4B~ | ~01001011~ | ~1~ | ~0~ | ~1~ | ~1~ | ~W = 1~, ~X = 1~, ~B = 1~ |
| ~0x4C~ | ~01001100~ | ~1~ | ~1~ | ~0~ | ~0~ | ~W = 1~, ~R = 1~ |
| ~0x4D~ | ~01001101~ | ~1~ | ~1~ | ~0~ | ~1~ | ~W = 1~, ~R = 1~, ~B = 1~ |
| ~0x4E~ | ~01001110~ | ~1~ | ~1~ | ~1~ | ~0~ | ~W = 1~, ~R = 1~, ~X = 1~ |
| ~0x4F~ | ~01001111~ | ~1~ | ~1~ | ~1~ | ~1~ | ~W = 1~, ~R = 1~, ~X = 1~, ~B = 1~ (todas as extensões) |
** Observações
- O prefixo REX só é válido no modo 64 bits.
- Pode ser necessário mesmo com operandos de 32 bits se registradores estendidos
forem usados.
** Exemplo de desmontagem
#+begin_example
48 89 c8 => mov rax, rcx
#+end_example
Nesse caso:
- ~48~: É o prefixo REX com ~W = 1~, ~R = 0~, ~X = 0~, ~B = 0~ (operandos de 64 bits).
- ~89~: OpCode ~mov r/m, reg~ (como primeiro operando é ~r/m~, temos que ver o byte ModR/M).
- ~c8~: Byte ModR/M, onde...
#+begin_example
Bits: 7 8 | 5 4 3 | 2 1 0
modo | origem | destino
c8 → 11 | 001 | 000
regs | rcx | rax
#+end_example
Portanto... ~48 89 c8 => mov rax, rcx~
** Tabela de registradores no byte ModR/M
O modo ~11~ indica que os dois operandos estão em registradores. Os 3 bits
dos campos ~reg~ e ~r/m~ indicam os registradores, com ou sem extensão via
prefixo ~REX~.
| Código | Reg. | ~REX.R~ ou ~REX.B~ |
|--------+------+----------------|
| ~000~ | ~rax~ | ~r8~ |
| ~001~ | ~rcx~ | ~r9~ |
| ~010~ | ~rdx~ | ~r10~ |
| ~011~ | ~rbx~ | ~r11~ |
| ~100~ | ~rsp~ | ~r12~ |
| ~101~ | ~rbp~ | ~r13~ |
| ~110~ | ~rsi~ | ~r14~ |
| ~111~ | ~rdi~ | ~r15~ |