Assembly x86/Registos
A arquitetura x86 tem 8 registradores de uso geral (General Purpose Registers - GPR), 6 registradores de segmento, 1 registrador de flags e um Apontador de Execução (Instruction Pointer). (FIXME: no AMD64/EM64T há mais de 8 GPRs)
Registradores de Uso Geral
[editar | editar código-fonte]Os 8 GPRs, ou Registradores de Uso Geral, são os seguintes (por ordem de introdução na pilha ao executar a instrução PUSHAD):
- EAX - Acumulador. Usado em operações aritméticas.
- ECX - Contador. Usado em loops.
- EDX - Registrador de Dados. Usado em operações de entrada/saída e em multiplicações e divisões. É também uma extensão do Acumulador.
- EBX - Base. Usado para apontar para dados no segmento DS.
- ESP - Apontador da Pilha (Stack Pointer). Aponta para o topo da pilha (endereço mais baixo dos elementos da pilha).
- EBP - Apontador da base do frame. Usado para acessar argumentos de procedimentos passados pela pilha.
- ESI - Índice da fonte de dados a copiar (Source Index). Aponta para dados a copiar para DS:EDI.
- EDI - Índice do destino de dados a copiar (Destination Index). Aponta para o destino dos dados a copiar de DS:ESI.
Estes 8 registradores têm 32 bits cada um e dizem-se Estendidos. Os 16 bits de ordem mais baixa de cada um dos registradores podem ser acessados através das versões não estendidas destes. As versões de 16 bits têm os mesmo nomes que as de 32 bits, com exceção de a letra E ser retirada (ex: EAX → AX). As versões estendidas dos registradores não existem em gerações anteriores à 80386 ― a primeira geração de processadores 32 bits da arquitetura x86.
As versões não estendidas dos quatro primeiros GPRs dividem-se ainda em dois grupos de 8 bits cada um. O octeto (byte) de ordem mais alta é acessado trocando o X por um H (exemplo: AX → AH), e o octeto de ordem mais baixa trocando o X por um L (ex: AX → AL).
Nota: Nos processadores da arquitetura AMD64/EM64T, os GPRs têm 64 bits e pode-se acessar a totalidade dos bits através dos nomes RAX, RCX, RDX, etc. Adicionalmente, existem ainda mais oito GPRs, de 64 bits cada um. Isto só é válido se o processador estiver em Modo Longo.
Registradores de segmento
[editar | editar código-fonte]Há 6 registradores de segmento.
- CS - Segmento do Código
- DS - Segmento de Dados
- ES - Segmento com dados extra
- FS - Segmento com mais dados
- GS - Segmento com ainda mais dados
- SS - Segmento da Pilha (Stack)
Os segmentos são uma idiossincrasia da arquitetura x86, não existindo em praticamente mais nenhuma arquitetura. Sendo assim, os compiladores de linguagens de alto nível geralmente optam por ignorar os segmentos. Por essa razão, os sistemas operativos modernos para x86 (incluindo o Windows e o Linux) tipicamente fazem todos os registradores de segmento apontar para o mesmo segmento de 4GB. As exceções a essa regra são geralmente o FS e o GS, que são usados para isolar as seções de dados das diferentes threads de um mesmo processo. As outras arquiteturas utilizam registradores especiais chamados registradores de thread para esse efeito, os quais não existem no x86.
Registrador das flags
[editar | editar código-fonte]O registrador das flags é chamado EFLAGS (Extended Flags) nas arquiteturas de 32 bits, sendo a sua versão de 16 bits chamada simplesmente FLAGS. Tal como com os GPRs, os processadores x86 anteriores ao i386 não possuem a versão de 32 bits. Nos processadores de 64 bits, este registrador também tem 64 bits e chama-se RFLAGS.
No esquema abaixo, os 16 bits menos significativos aparecem a cinza, enquanto que os bits a azul apenas existem em processadores da geração do i386 ou posteriores.
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ID | VIP | VIF | AC | VM | RF |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | NT | IOPL | OF | DF | IF | TF | SF | ZF | 0 | AF | 0 | PF | 1 | CF |
Ao carregar um novo valor no EFLAGS, os bits que aparecem no esquema como 1 ou 0 devem ser carregados como tal, de modo a preservar a compatibilidade do software com gerações futuras da arquitetura.
Note-se que utilizar um método convencional para acessar este registrador produz um erro do montador (assembler), uma vez que o x86 não fornece nenhuma forma de acessar diretamente o registrador das flags. Para modificar ou ler o eflags é necessário utilizar a instrução pushf (16 bits) ou pushaf (32 bits).
O apontador de execução
[editar | editar código-fonte]O apontador de execução, ou Instruction Pointer (genericamente conhecido na ciência da computação por Program Counter), do x86 é um registrador interno que aponta para a próxima instrução a ser executada.
O seu nome é EIP e a parte que contem os 16 bits menos significativos denomina-se IP. Tal como no caso do registrador das flags, não é possível utilizar um método convencional para acessar o apontador de Execução. Ele tem de ser introduzido no stack por meio de uma instrução call ou semelhante.