Revisão da Família 80x86

A família 80x86 surgiu em 1981 com o 8086 e seu membro mais novo é o Pentium que foi lançado treze anos depois, em 1994. Estes processadores são sempre compatíveis com seus respectivos antecessores mas cada nova geração recebeu novas características e maior velocidade que a anterior. Hoje existem poucos computadores utilizando os processadores 8088 e 8086 uma vez que são desatualizados e lentos. O número de computadores baseados no 286 e 386 está em franco declínio em função da grande demanda por desempenho nos softwares recentes. Mesmo os 486 estão sendo substituídos por Pentiums. Com as CPUs Pentium PRO e MMX a Intel continua acrescentando novas funções e ampliando o desempenho de seus processadores.

Representação de números em binário

Antes de começarmos a entender como programar em assembly será melhor tentar entender como são representados números em computadores. Números são armazenados em binário, ou seja, na base 2. Existem vários termos que são utilizados para descrever diferentes tamanhos de números e eu descreverei o que eles significam.

1 BIT: 0

Um bit é a mais simples porção de dados que existe. Pode valer um ou zero.

1 NIBBLE: 0000
4 BITS

O NIBBLE possui 4 bits, ou meio byte. Observe que ele pode atingir o valor máximo de 15 (1111 = 15). Esta é a base do sistema de numeração hexadecimal (base 16) o qual é utilizado pela facilidade de seu entendimento. Os números hexadecimais se utilizam dos algarismos 0 (zero) ao F e são terminados por um h para se indicar que se tratam de números de base 16. Portanto Fh = 15 decimal. Números hexadecimais que começam com uma letra recebem um 0 (zero) como prefixo.

1 BYTE 00000000
2 NIBBLES
8 BITS

Um BYTE possui 8 bits ou 2 nibbles. Um BYTE possui um valor máximo de 0FFh (255 decimal). Uma vez que um BYTE equivale a 2 nibbles a sua representação hexadecimal é feita com dois dígitos hexadecimais em seqüência, por exemplo 3Dh. O byte possui o mesmo tamanho dos registradores de 8 bits sobre os quais discutiremos mais tarde.

1 WORD 0000000000000000
2 BYTES
4 NIBBLES
16 BITS

Uma WORD (ou palavra) constitui-se de dois bytes reunidos. Uma WORD possui o valor máximo de 0FFFFh (65.535). Uma vez que uma WORD é igual a quatro nibbles ela é representada por quatro dígitos hexadecimais. Ela tem o mesmo tamanho dos registradores de 16 bits.

Registradores

Registradores são o local da CPU onde um número pode ser armazenado e manipulado. Existem três tamanhos de registradores: 8 bits, 16 bits e no 386 em diante 32 bits. Há quatro tipos diferentes de registradores; registradores de uso geral, registradores de segmento, registradores de índice e registradores de pilha. Aqui estão, primeiramente, as descrições dos registradores principais. Os Registradores de pilha e de segmento serão abordados mais tarde.

Conjunto de registradores do 8086/88
Registradores de Uso Geral

Registradores de Uso Geral

Estes são registradores de 16 bits. Existem quatro registradores de uso geral; AX, BX, CX e DX. Eles são divididos em registradores de 8 bits. AX é dividido em AH, o qual contém o byte mais significativo, e AL, que contém o byte menos significativo. No 386 em diante também existem registradores de 32 bits, estes possuem os mesmos nomes dos registradores de 16 bits mas com um 'E' na frente, por exemplo EAX. Você pode usar AL, AH, AX e EAX separadamente e tratá-los como registradores separados em alguns casos.

Se AX contiver o número 24689 decimal:

AH AL
01100000 01110001

AH terá o valor 96 e AL o valor 113. Se você somar um a AL ele terá o valor 114 e AH não será modificado. SI, DI, SP e BP também podem ser utilizados como registradores de uso geral mas possuem usos mais específicos. Eles não se dividem em duas metades.

Registradores de Índice

Estes são chamados, algumas vezes, de registradores de ponteiros e possuem 16 bits. São utilizados principalmente para instruções com strings. Existem três registradores de índice: SI (source index), DI (destination index) e IP (instruction pointer). No 386 em diante também existem registradores de índice com 32 bits: EDI e ESI. Você também pode usar BX para indexar strings.

IP é um registrador de índice mas não pode ser manipulado diretamente já que ele armazena o endereço da próxima instrução a ser executada.

Registradores de pilha

BP e SP são registradores de pilha e são utilizados quando se está trabalhando com a pilha. Eles serão analisados quando estivermos falando sobre a pilha, mais tarde.

Segmentos e offsets

Os projetistas originais do 8088 decidiram que ninguém jamais precisaria utilizar mais que um megabyte de memória então eles criaram a CPU que não tinha a capacidade de acessar mais do que isto. Havia o problema de que para acessar um megabyte completamente são necessários 20 bits para o endereço. Os registradores só possuem 16 bits e eles não queriam usar dois registradores lado a lado porque isto resultaria em um endereço de 32 bits e eles achavam isto demais para qualquer usuário. Eles surgiram com o que consideraram uma maneira inteligente de resolver este problema: segmentos e offsets. É uma forma de criar endereçamento com dois registradores mas não em 32 bits.

OFFSET = SEGMENTO * 16
SEGMENTO = OFFSET / 16 (os 4 bits inferiores são perdidos)

Um registrador contém o segmento e outro registrador contém o offset. Se você colocar os dois registradores juntos você obtém um endereço de 20 bits.

SEGMENTO 0010010000010000----
OFFSET ----0100100000100010
endereço de 20 bits 00101000100100100010

DS armazena o Segmento e SI armazena o offset. Como ambos possuem 16 bits os endereços se sobrepõem. Desta forma o par DS:SI é usado para formar um endereço de 20 bits. O segmento está em DS e o offset está em SI. A notação padrão para um par Segmento/Offset é: SEGMENTO:OFFSET

Os registradores de segmentos são: CS, DS, ES, SS. No 386 e demais CPUs também existem o FS e o GS.

Os registradores de offset são: BX, DI, SI, BP, SP, IP. No 386 e demais CPUs, no modo protegido, QUALQUER registrador de uso geral (mas não registradores de segmento) pode ser usado como um registrador de Offset. (Exceto o IP, o qual você não pode manipular diretamente).

Se você está pensando agora que assembly deve ser realmente difícil e que você não entendeu nada de segmentos e offsets então não se preocupe. Eu não os entendi no começo mas insisti e acabei descobrindo que eles não são tão difíceis de usar na prática.

A Pilha

Como só existem seis registradores para uso com a maioria das operações você está provavelmente imaginando como se virar com isto. É fácil. Existe uma coisa chamada de Pilha que é uma área de memória na qual você pode salvar e recuperar valores.

Esta é uma área de memória parecida com uma pilha de pratos. O último que você colocar é o primeiro que pode ser retirado. Isto é chamado, as vezes, de Last On First Off (LOFO) ou Last In First Out (LIFO).

Pilha do processador 8086/88
Como a pilha é organizada

Se outra porção de dados for colocada na pilha ela cresce para baixo. Como você pode ver a pilha começa em um endereço alto e cresce em direção a endereços menores. Você precisa ter certeza de que não colocará dados em excesso na pilha ou ela transbordará.

Retornar para o Sumário