pbn/docs/prefixo-rex.org

87 lines
4.1 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

* 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~ |