# ModR/M e SIB

Como já foi mencionado anteriormente o byte ModR/M é usado em algumas instruções para especificar o operando na memória ou registrador.

Em Assembly existem dois "tipos" de instruções que recebem dois operandos:

1. As que tem um operando registrador e imediato. Exemplo: `mov eax, 123`&#x20;
2. As que tem um operando na memória ou dois operandos registradores. Exemplos: `mov [ebx], 123` e `mov eax, ebx`.

O primeiro tipo não precisa do byte ModR/M, pois o registrador destino é especificado nos 3 últimos bits do byte do [opcode](/assembly/apendices/codigo-de-maquina/opcode.md). Por exemplo o opcode `B8` da instrução `mov eax, 123` é o seguinte em binário: `10111000` Onde o número zero (`000`) é o código para identificar o registrador EAX.

{% content-ref url="/pages/Q6aigICLm6yM6yWbWHtH" %}
[Codificação dos registradores](/assembly/apendices/codigo-de-maquina/codificacao-dos-registradores.md)
{% endcontent-ref %}

Um jeito mais simples de especificar esse campo no opcode sem precisar lidar com binário é simplesmente somar o opcode "base" (correspondente ao uso de AL/AX/EAX) mais o código do registrador. Por exemplo se a instrução `B8` (`B8 + 0`) corresponde a `mov eax, 123`, então o opcode `BB` (`B8 + 3`) é `mov ebx, 123`. E se eu quiser fazer `mov bx, 123` basta adicionar o prefixo `66` à instrução.

Já as instruções do segundo tipo usam o byte ModR/M para definir o operando destino na memória (no caso de instruções sem o operando registrador) ou os dois operandos. Onde o byte ModR/M consiste nos três campos:

* `MOD` - Os primeiros 2 bits que definem o "modo" do operando R/M.
* `REG` - Os 3 próximos bits que definem o código do operando registrador.
* `R/M` - Os 3 últimos bits que definem o código do operando R/M.

O byte define 2 operandos:

1. Um operando que é sempre um registrador, definido no campo `REG`.
2. Um operando que pode ser um registrador ou operando na memória.

Para que o campo `R/M` defina também o código de um registrador, assim como o `REG`, o valor 3 (`11` em binário) deve ser usado no campo `MOD`.

{% hint style="info" %}
Um adendo sobre o byte ModR/M é que em algumas instruções o campo `REG` é usado como uma extensão do opcode.\
\
É o caso por exemplo das instruções `inc dword [ebx]` (`FF 03`) e `dec dword [ebx]` (`FF 0B`) que contém o mesmo byte de opcode mas fazem operações diferentes.\
\
Repare como o campo R/M é necessário para especificar o operando na memória mas o REG fica "sobrando", por isso os engenheiros da Intel tomaram essa decisão minimamente confusa (~~vulgo gambiarra~~), afim de aproveitar dessa peculiaridade em instruções que precisam de um operando na memória mas não precisam de um operando registrador.
{% endhint %}

Para os demais valores do campo `MOD` os seguintes endereçamentos são feitos de acordo com o valor de `R/M`:

### Endereçamento em 16-bit

#### MOD 00

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>000</td><td><code>[BX+SI]</code></td></tr><tr><td>001</td><td><code>[BX+DI]</code></td></tr><tr><td>010</td><td><code>[BP+SI]</code></td></tr><tr><td>011</td><td><code>[BP+DI]</code></td></tr><tr><td>100</td><td><code>[SI]</code></td></tr><tr><td>101</td><td><code>[DI]</code></td></tr><tr><td>110</td><td>displacement 16-bit</td></tr><tr><td>111</td><td><code>[BX]</code></td></tr></tbody></table>

#### MOD 01

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>000</td><td><code>[BX+SI]</code> + displacement 8-bit</td></tr><tr><td>001</td><td><code>[BX+DI]</code> + displacement 8-bit</td></tr><tr><td>010</td><td><code>[BP+SI]</code> + displacement 8-bit</td></tr><tr><td>011</td><td><code>[BP+DI]</code> + displacement 8-bit</td></tr><tr><td>100</td><td><code>[SI]</code> + displacement 8-bit</td></tr><tr><td>101</td><td><code>[DI]</code> + displacement 8-bit</td></tr><tr><td>110</td><td><code>[BP]</code> + displacement 8-bit</td></tr><tr><td>111</td><td><code>[BX]</code> + displacement 8-bit</td></tr></tbody></table>

#### MOD 10

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>000</td><td><code>[BX+SI]</code> + displacement 16-bit</td></tr><tr><td>001</td><td><code>[BX+DI]</code> + displacement 16-bit</td></tr><tr><td>010</td><td><code>[BP+SI]</code> + displacement 16-bit</td></tr><tr><td>011</td><td><code>[BP+DI]</code> + displacement 16-bit</td></tr><tr><td>100</td><td><code>[SI]</code> + displacement 16-bit</td></tr><tr><td>101</td><td><code>[DI]</code> + displacement 16-bit</td></tr><tr><td>110</td><td><code>[BP]</code> + displacement 16-bit</td></tr><tr><td>111</td><td><code>[BX]</code> + displacement 16-bit</td></tr></tbody></table>

### Endereçamento em 32-bit

#### MOD 00

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>000</td><td><code>[eax]</code></td></tr><tr><td>001</td><td><code>[ecx]</code></td></tr><tr><td>010</td><td><code>[edx]</code></td></tr><tr><td>011</td><td><code>[ebx]</code></td></tr><tr><td>100</td><td>SIB</td></tr><tr><td>101</td><td>displacement 32-bit</td></tr><tr><td>110</td><td><code>[esi]</code></td></tr><tr><td>111</td><td><code>[edi]</code></td></tr></tbody></table>

#### MOD 01

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>000</td><td><code>[eax]</code> + displacement 8-bit</td></tr><tr><td>001</td><td><code>[ecx]</code> + displacement 8-bit</td></tr><tr><td>010</td><td><code>[edx]</code> + displacement 8-bit</td></tr><tr><td>011</td><td><code>[ebx]</code> + displacement 8-bit</td></tr><tr><td>100</td><td>SIB + displacement 8-bit</td></tr><tr><td>101</td><td><code>[ebp]</code> + displacement 8-bit</td></tr><tr><td>110</td><td><code>[esi]</code> + displacement 8-bit</td></tr><tr><td>111</td><td><code>[edi]</code> + displacement 8-bit</td></tr></tbody></table>

#### MOD 10

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>000</td><td><code>[eax]</code> + displacement 32-bit</td></tr><tr><td>001</td><td><code>[ecx]</code> + displacement 32-bit</td></tr><tr><td>010</td><td><code>[edx]</code> + displacement 32-bit</td></tr><tr><td>011</td><td><code>[ebx]</code> + displacement 32-bit</td></tr><tr><td>100</td><td>SIB + displacement 32-bit</td></tr><tr><td>101</td><td><code>[ebp]</code> + displacement 32-bit</td></tr><tr><td>110</td><td><code>[esi]</code> + displacement 32-bit</td></tr><tr><td>111</td><td><code>[edi]</code> + displacement 32-bit</td></tr></tbody></table>

### Endereçamento em 64-bit

{% hint style="info" %}
Devido ao [prefixo REX](/assembly/apendices/codigo-de-maquina/prefixo-rex.md) o campo R/M é estendido em 1 bit no modo de 64-bit.
{% endhint %}

#### MOD 00

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>0000</td><td><code>[rax/eax]</code></td></tr><tr><td>0001</td><td><code>[rcx/ecx]</code></td></tr><tr><td>0010</td><td><code>[rdx/edx]</code></td></tr><tr><td>0011</td><td><code>[rbx/ebx]</code></td></tr><tr><td>0100</td><td>SIB</td></tr><tr><td>0101</td><td><code>[rip/eip]</code> + displacement 32-bit</td></tr><tr><td>0110</td><td><code>[rsi/esi]</code></td></tr><tr><td>0111</td><td><code>[rdi/edi]</code></td></tr><tr><td>1000</td><td><code>[r8/r8d]</code></td></tr><tr><td>1001</td><td><code>[r9/r9d]</code></td></tr><tr><td>1010</td><td><code>[r10/r10d]</code></td></tr><tr><td>1011</td><td><code>[r11/r11d]</code></td></tr><tr><td>1100</td><td>SIB</td></tr><tr><td>1101</td><td><code>[rip/eip]</code> + displacement 32-bit</td></tr><tr><td>1110</td><td><code>[r14/r14d]</code></td></tr><tr><td>1111</td><td><code>[r15/r15d]</code></td></tr></tbody></table>

#### MOD 01

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>0000</td><td><code>[rax/eax]</code> + displacement 8-bit</td></tr><tr><td>0001</td><td><code>[rcx/ecx]</code> + displacement 8-bit</td></tr><tr><td>0010</td><td><code>[rdx/edx]</code> + displacement 8-bit</td></tr><tr><td>0011</td><td><code>[rbx/ebx]</code> + displacement 8-bit</td></tr><tr><td>0100</td><td>SIB + displacement 8-bit</td></tr><tr><td>0101</td><td><code>[rbp/ebp]</code> + displacement 8-bit</td></tr><tr><td>0110</td><td><code>[rsi/esi]</code> + displacement 8-bit</td></tr><tr><td>0111</td><td><code>[rdi/edi]</code> + displacement 8-bit</td></tr><tr><td>1000</td><td><code>[r8/r8d]</code> + displacement 8-bit</td></tr><tr><td>1001</td><td><code>[r9/r9d]</code> + displacement 8-bit</td></tr><tr><td>1010</td><td><code>[r10/r10d]</code> + displacement 8-bit</td></tr><tr><td>1011</td><td><code>[r11/r11d]</code> + displacement 8-bit</td></tr><tr><td>1100</td><td>SIB + displacement 8-bit</td></tr><tr><td>1101</td><td><code>[r13/r13d]</code> + displacement 8-bit</td></tr><tr><td>1110</td><td><code>[r14/r14d]</code> + displacement 8-bit</td></tr><tr><td>1111</td><td><code>[r15/r15d]</code> + displacement 8-bit</td></tr></tbody></table>

#### MOD 10

<table><thead><tr><th width="150">R/M</th><th>Endereçamento</th></tr></thead><tbody><tr><td>0000</td><td><code>[rax/eax]</code> + displacement 32-bit</td></tr><tr><td>0001</td><td><code>[rcx/ecx]</code> + displacement 32-bit</td></tr><tr><td>0010</td><td><code>[rdx/edx]</code> + displacement 32-bit</td></tr><tr><td>0011</td><td><code>[rbx/ebx]</code> + displacement 32-bit</td></tr><tr><td>0100</td><td>SIB + displacement 32-bit</td></tr><tr><td>0101</td><td><code>[rbp/ebp]</code> + displacement 32-bit</td></tr><tr><td>0110</td><td><code>[rsi/esi]</code> + displacement 32-bit</td></tr><tr><td>0111</td><td><code>[rdi/edi]</code> + displacement 32-bit</td></tr><tr><td>1000</td><td><code>[r8/r8d]</code> + displacement 32-bit</td></tr><tr><td>1001</td><td><code>[r9/r9d]</code> + displacement 32-bit</td></tr><tr><td>1010</td><td><code>[r10/r10d]</code> + displacement 32-bit</td></tr><tr><td>1011</td><td><code>[r11/r11d]</code> + displacement 32-bit</td></tr><tr><td>1100</td><td>SIB + displacement 32-bit</td></tr><tr><td>1101</td><td><code>[r13/r13d]</code> + displacement 32-bit</td></tr><tr><td>1110</td><td><code>[r14/r14d]</code> + displacement 32-bit</td></tr><tr><td>1111</td><td><code>[r15/r15d]</code> + displacement 32-bit</td></tr></tbody></table>

### Byte SIB

Os endereçamentos com R/M `100` (em 32-bit e 64-bit) são os que usam o byte SIB (exceto `MOD 11`), que como já foi explicado anteriormente contém os campos **Scale**, **Index** e **Base** que são calculados de maneira equivalente a expressão:

```
base + index * scale
```

Onde o campo **scale** são os 2 primeiros bits, onde seu valor numérico é equivalente aos seguintes fatores de escala:

* `00` - Não multiplica o **index**
* `01` - Multiplica o **index** por 2
* `10` - Multiplica o **index** por 4
* `11` - Multiplica o **index** por 8

Já os campos **index** e **base** contém 3 bits cada e os mesmos armazenam o [código dos registradores](/assembly/apendices/codigo-de-maquina/codificacao-dos-registradores.md) que serão usados. Os bits dos campos no byte seguem a ordem que o próprio nome sugere. Como em: `SSIIIBBB`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mentebinaria.gitbook.io/assembly/apendices/codigo-de-maquina/modr-m-e-sib.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
