diff --git a/docs/prefixo-rex.org b/docs/prefixo-rex.org new file mode 100644 index 0000000..3b2632a --- /dev/null +++ b/docs/prefixo-rex.org @@ -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 (~r8–r15~) +- 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 | +|-----+------+--------------------------------------------------------------------| +| ~7–4~ | ~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 (~0x40–0x4F~) + +| 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~ | +