# Codificação dos registradores

Em modo de 16-bit e 32-bit cada registrador é identificado usando um número de 3 bits, permitindo assim identificar uma variação de 8 registradores diferentes. Porém vários registradores compartilham do mesmo código, e qual especificamente será usado varia de acordo com a instrução sendo utilizada e o tamanho do operando.

Por exemplo [instruções da FPU](https://mentebinaria.gitbook.io/assembly/aprofundando-em-assembly/usando-instrucoes-da-fpu) irão sempre usar algum registrador ST0\~ST7, então o código em uma instrução da FPU será usado para identificar algum deles.

Como por exemplo a instrução `fld st3` que em código de máquina fica `D9 C3`, onde `C3` é o ModR/M:

```
MOD -> 11
REG -> 000
R/M -> 011
```

Repare que essa instrução usa o campo `REG` como extensão do opcode e o R/M é usado para especificar o operando. Não coincidentemente o código 3 (`0b011`) é usado para identificar o registrador ST3.

Já instruções que usam [registradores de propósito geral](https://mentebinaria.gitbook.io/assembly/a-base/registradores-de-proposito-geral), qual especificamente será usado depende do tamanho do operando na instrução (veja [Atributos e prefixos](https://mentebinaria.gitbook.io/assembly/apendices/codigo-de-maquina/atributos-e-prefixos)).

Por exemplo as seguintes instruções compiladas em modo de 64-bit:

```
mov eax, 0x11223344                    b8 44 33 22 11
mov ax, 0x1122                         66 b8 22 11
mov al, 0x11                           b0 11
```

Se convertermos esses opcodes em binário teremos o seguinte:

```
B8 -> 10111000
B0 -> 10110000
```

Esses dois opcodes usam os 3 últimos bits para identificar o registrador. Veja que o mesmo código `000` acabou sendo usado para identificar EAX, AX e AL.

Isso porque na primeira instrução o atributo **operand-size** padrão de 32-bit foi usado, então o registrador EAX é usado na instrução. Já na segunda o prefixo **operand-size override** (byte `66`) foi usado, assim o **operand-size** era de 16-bit e portanto o registrador AX é usado.

Já a última instrução é exclusivamente usada para operandos de 8-bit, e portanto o registrador AL é usado.

## Tabela de códigos

Como já foi explicado no tópico que fala sobre o [prefixo REX](https://mentebinaria.gitbook.io/assembly/apendices/codigo-de-maquina/prefixo-rex), esse prefixo estende os campos usados em ModR/M, SIB e o campo `REG`do opcode em 1 bit. Daí assim o código usado para identificar o registrador, em modo de 64-bit, tem 4 bits de tamanho.

A tabela abaixo lista os códigos usados para identificar os registradores. Lembrando que o bit mais significativo indica um dos bits do REX ligado, ou seja, só é utilizado em modo de 64-bit.

<table><thead><tr><th width="184.57142857142856">Código</th><th>Registrador</th></tr></thead><tbody><tr><td><code>0000</code></td><td><code>AL/AX/EAX/RAX/ST0/MM0/XMM0</code></td></tr><tr><td><code>0001</code></td><td><code>CL/CX/ECX/RCX/ST1/MM1/XMM1</code></td></tr><tr><td><code>0010</code></td><td><code>DL/DX/EDX/RDX/ST2/MM2/XMM2</code></td></tr><tr><td><code>0011</code></td><td><code>BL/BX/EBX/RBX/ST3/MM3/XMM3</code></td></tr><tr><td><code>0100</code></td><td><code>AH/SP/ESP/RSP/ST4/MM4/XMM4</code></td></tr><tr><td><code>0101</code></td><td><code>CH/BP/EBP/RBP/ST5/MM5/XMM5</code></td></tr><tr><td><code>0110</code></td><td><code>DH/SI/ESI/RSI/ST6/MM6/XMM6</code></td></tr><tr><td><code>0111</code></td><td><code>BH/DI/EDI/RDI/ST7/MM7/XMM7</code></td></tr><tr><td><code>1000</code></td><td><code>R8B/R8W/R8D/R8/ST0/MM0/XMM8</code></td></tr><tr><td><code>1001</code></td><td><code>R9B/R9W/R9D/R9/ST1/MM1/XMM9</code></td></tr><tr><td><code>1010</code></td><td><code>R10B/R10W/R10D/R10/ST2/MM2/XMM10</code></td></tr><tr><td><code>1011</code></td><td><code>R11B/R11W/R11D/R11/ST3/MM3/XMM11</code></td></tr><tr><td><code>1100</code></td><td><code>R12B/R12W/R12D/R12/ST4/MM4/XMM12</code></td></tr><tr><td><code>1101</code></td><td><code>R13B/R13W/R13D/R13/ST5/MM5/XMM13</code></td></tr><tr><td><code>1110</code></td><td><code>R14B/R14W/R14D/R14/ST6/MM6/XMM14</code></td></tr><tr><td><code>1111</code></td><td><code>R15B/R15W/R15D/R15/ST7/MM7/XMM15</code></td></tr></tbody></table>
