O 8086 possui um barramento de memória de 20-bits, o que permite o endereçamento de 1.048.576(0 a 0xFFFF) locais acessíveis para endereçar código, Pilha, dados, RAM e outros. Nesta parte do tutorial vamos estudar sobre armazenamento, segmentação, mapeamento e outros assuntos.

Os dados armazenados pelo 8086 utilizam o formato Little-endian(LE), o que significa que um valor tem seu byte menos significativo armazenado primeiro, seguido de seu byte mais significativo.

Exemplo 1: Big Endian

$1234
$ABCD

Exemplo 2: Little Endian

$3412
$CDAB

Tab. 1: Um trecho de memória contendo valores do Ex. 2
SEG:OFF 00 01 02 03 (...) 0C 0D 0E 0F
0000:0000 34 12 -- -- (...) CD AB -- --
0000:0010 -- -- -- -- (...) -- -- -- --

Os valores com tamanho de 16-bits no 8086 são vistos como LSB e MSB, o que significam Least Significant Byte e Most Significant Byte. Em uma tradução literal Byte Menos Significativo e Byte Mais Significativo. O LSB é o byte mais à direita e o MSB é o byte mais à esquerda de um valor 16-bits.

Word
Byte 1(LSB) Byte 0(MSB)
34 12

O usuário/programador não precisa se preocupar como os dados são armazenados em memória, pois tanto a leitura quanto a escrita são feitas automaticamente no formato LE. Valores salvos e recuperados da Stack também respeitam esse formato.

Quando um valor 16-Bits está contido em um registrador de uso geral, ponteiro, indíce ou segmento, os dados são armazenados no formato Big Endian.

Exemplo 3

$1234
$ABCD

O espaço de memória endereçável do 8086 é dividido, por padrão, em segmentos de 64KB. Esses segmentos podem ser sobrepostos ou não sobrepostos.

Tab. 2: segmentos
Início Fim
00000 0FFFF
10000 01FFFF
(...) -
20000 2FFFF
(...) -
40000 4FFFF
(...) -
80000 8FFFF
C0000 CFFFF
(...) -

O 8086 permite que esses segmentos possam ser sobrepostos, sem sobreposição de dados, o que permite que um mesmo local de memória possa ser acessado de formas diferentes.

Tab. 3: Segmentos
Endereço Segmento 0 Segmento 1 Segmento 2
00000 Início Início
0FFFF Fim Fim
10000 Início
1FFFF Fim
20000
(...)

Utilizando os registradores de segmento DS, SS e ES em conjunto com os registradores de indexação SI, DI e BP, é possível acessar todos os locais de memória contidos nesses segmentos de 64K mencionados anteriormente.

O programador não precisa se preocupar no controle das segmentações, onde dados ficam armazenados, exceto quando informados manualmente. Tudo é feito automaticamente pelo compilador/assembler.

Como o 8086 utiliza um par de registradores para acessar endereços de memória, esses endereços são divididos em Lógicos e Físicos.

Um endereço lógico é montado a partir de registradores de segmento e indexadores. Por exemplo, o endereço da instrução corrente é montado a partir de CS e IP como na notação abaixo:

Notação

[RS:VAL]

Onde

RS: Registrador de segmento
VAL: Registrador de índice, endereço direto ou outro

Como exemplo básico, quando temos os CS armazenando o endereço 0x12 e IP armazenando 0x2 temos:

Ex:

[0012:0002]

Para que a instrução seja recuperada, o 8086 realiza um cálculo para converter um endereço lógico em físico de acordo com a fórmula abaixo:

Fórmula:

RS*0x10 + RI = Endereço físico

Mais uma vez, o programador não precisa se preocupar com os cálculos mostrados acima, pois são realizados automaticamente pelo processador.

Os hardwares listados anteriormente na seção Uso utilizam a memória do 8086 dividida em pequenas partes. Essas partes são mapeadas para uso de outros componentes do hardware para leitura e escrita de dados. Tendo todas as partes definidas, temos o tão conhecido mapeamento de memória.

Tab. 4: Exemplo de mapeamento
Região Tamanho Uso Descrição
0x000000 - 0x0003FF 1KB RAM Vetor de Interrupções
0x000400 - 0x0005FF 512KB RAM BIOS
0x000600 - 0x07FFFF 512KB RAM Memória
0x080000 - 0x09FFFF 128KB RAM Memória
0x0A0000 - 0x0A3FFF 16KB RAM RAM de Vídeo
0x0A4000 - 0x0A4FFF 4KB RAM Fonte de caracteres

O uso, definição do mapeamento é de total responsabilidade do hardware que utiliza o 8086 como processador principal. O 8086 possui apenas a segmentação que deve ser levada em consideração.

Uma forma de se comunicar ou trocar informações com periféricos ligados ao processador é via registradores mapeados em memória.

Esses registradores são um espaço de memória resevado para leitura e escrita de dados para comunicação com outros chips utilizados no hardware, por exemplo, vídeo e áudio.

Abaixo, alguns exemplos de dispositivos e outros periféricos que podem utilizar registradores mapeados em memória.

Dispositivos
  1. Mouse
  2. Teclado
  3. Joystick
  4. Áudio
  5. Vídeo

Por padrão, o 8086 utiliza o conceito de entrada e saída de dados via porta. As instruções de INPUT(IN) e OUTPUT(OUT) são responsáveis por enviar e recuperar dados de periféricos.

Como exemplo real de registradores mapeados em memória, temos os registradores abaixo destinados à comunicação com um processadores vídeo.

Tab. 5: Entrada e Saída
Porta Descrição
$00 Display Control
$14 LCD Control
$90 Sound Channel Control
$A0 System Control
$B2 Interrupt Enable

O uso, definição de porta e outras configurações é de total responsabilidade do hardware que utiliza o 8086 como processador principal.

Como o 8086 possui apenas 1 MByte de memória endereçável, muitos hardwares utilizam um sistema de mapeamento de bancos que têm como objetivo armazenar bancos trocáveis de tamanhos específicos em um ou mais locais de memória. Dessa forma, é possível executar programas maiores que 1MB.

Abaixo, um exemplo real de bancos de memória utilizando o 8086:

Tab. 6: Bancos de memória
Região Tamanho
000000-00FFFF 64KB
010000-01FFFF 64KB
020000-02FFFF 64KB
030000-03FFFF 64KB
040000-0FFFFF 1MB

O uso, definição de endereço e outras configurações é de total responsabilidade do hardware que utiliza o 8086 como processador principal. O 8086 não possui nenhum mapeamento de banco nativo tendo apenas a segmentação de memória definida.

  1. 18/02/2025 - revisão 1 - ajustes pontuais
  2. 29/10/2024 - versão inicial