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