Tutoriais e Programação
AoA - Cap.3 - Os componentes básicos de um sistema
Seg 26 Fev 2007 09:02 |
- Detalhes
- Categoria: Art of Assembly
- Atualização: Sábado, 27 Fevereiro 2010 16:50
- Autor: vovó Vicki
- Acessos: 17242
O projeto operacional básico de um sistema de computador é chamado de arquitetura do computador. John Von Newmann, pioneiro no desenvolvimento de computadores, é o "pai" da arquitetura utilizada na maioria dos computadores atuais. Por exemplo, a família 80x86 utiliza a arquitetura de Von Neumann (VNA - Von Neumann Architecture). Um sistema Von Neumann típico tem três componentes principais: a unidade central de processamento (CPU - Central Processing Unit), a memória e a entrada/saída (E/S ou I/O - Input/Output). A forma como o projetista de um sistema combina estes componentes influi na performance do sistema.
Em máquinas VNA, como a família 80x86, a CPU é onde todas as ações ocorrem. Todas os cálculos acontecem dentro da CPU. As instruções da CPU e os dados ficam na memória até que sejam requeridos pela CPU. Para a CPU, muitos dispositivos de E/S se parecem com a memória porque a CPU pode armazenar dados em dispositivos de saída ou ler dados de dispositivos de entrada. A maior diferença entre memória e pontos de E/S é que os pontos de E/S geralmente estão associados a dispostivos externos.
{faqslider} :::: O barramento do sistema ::::
O barramento do sistema, também chamado de bus do sistema, conecta os vários componentes de uma máquina VNA. A família 80x86 tem três barramentos principais: o barramento de endereços, o barramento de dados e o barramento de controle. Um barramento é um conjunto de fios, pelos quais passam sinais elétricos, que ligam os componentes do sistema. Estes barramenteos variam de processador para processador, contudo, cada um dos barramentos transporta informações parecidas em todos os processadores. Por exemplo, o barramento de dados pode ter uma implementação diferente no 80386 e no 8088, mas ambos carregam dados entre o processador, os dispositivos de E/S e a memória.
Um componente típico do sistema 80x86 utiliza níveis lógicos padrão TTL. Isto significa que cada fio do barramento utiliza um nível de voltagem padrão para representar zero e um. Sempre especificaremos zero e um ao invés dos níveis elétricos reais porque estes níveis variam de processador para processador (especialmente em laptops).
O barramento de dados
Os processadores 80x86 utilizam um barramento de dados para distribuir dados entre os vários componentes do computador. O tamanho deste barramento varia bastante na famíla 80x86. De certa forma, este barramento define o "tamanho" do processador.
Nos sistemas 80x86 típicos, o barramento de dados contém 8, 16, 32 ou 64 linhas. Os microprocessadores 8088 e 80188 têm um barramento de dados de oito bits (oito linhas de dados). Os processadores 8086, 80186, 80286 e 80386SX têm um barramento de dados de 16 bits. O 80386DX, 80486, Pentium Overdrive têm um barramento de dados de 32 bits. Os processadores Pentium e Pentium Pro têm um barramento de dados de 64 bits. Futuras versões do chip poderão ter barramentos maiores.
Um barramento de dados de oito bits não limita o processador a tipos de dados de oito bits. Simplesmente significa que o processador pode acessar apenas um byte de dado por ciclo de memória (veja abaixo "O subsistema da memória"). Isto quer dizer que o barramento de oito bits em um 8088 pode transmitir apenas a metade da informação por unidade de tempo (ciclo de memória) comparado a um barramento de 16 bits num 8086. Portanto, processadores com um barramento de 16 bits são mais rápidos do que processadores com um barramento de oito bits. O tamanho do barramento de dados afeta a performance do sistema mais do que o tamanho de qualquer outro barramento.
Processador | Tamanho do Barramento de Dados |
---|---|
8088 | 8 |
80188 | 8 |
8086 | 16 |
80186 | 16 |
80286 | 16 |
80386SX | 16 |
80386DX | 32 |
80486 | 32 |
80586 Pentium (Pro) | 32 |
Com frequência ouve-se falar em processadores de 8, 16, 32 ou 64 bits. Como há uma pequena controvérsia a respeito do tamanho de um processador, muitas pessoas aceitam que o número de linhas de dados no processador determina o seu tamanho. Uma vez que os barramentos da família 80x86 são de 8, 16, 32 ou 64 bits, muitos acessos a dados são também de 8, 16, 32 ou 64 bits. Apesar de ser possível processar 12 bits de dados num 8088, muitos programadores processam 16 bits porque o processador buscará e manipulará 16 bits de qualquer forma. Isto é porque o processador sempre busca oito bits. Buscar 12 bits requer duas operações de oito bits na memória. Já que o processador busca 16 bits e não 12, a maioria dos programadores utiliza todos os 16 bits. Em geral, manipular dados que tenham 8, 16, 32 ou 64 bits é mais eficiente.
Embora os membros de 16, 32 e 64 bits da família 80x86 possam processar dados até a largura do barramento, eles também podem acessar unidades menores de memória - de 8, 16 ou 32 bits. Então, qualquer coisa que se possa fazer com um barramento de dados pequeno também pode ser feita com um barramento de dados maior; o barramento de dados maior, contudo, pode acessar a memória mais rapidamete e pode acessar fragmentos de dados maiores em apenas uma operação de memória. Você lerá sobre a exata natureza destes acessos de memória mais adiante.
O barramento de endereços
O barramento de dados nos processadores 80x86 transfere informação entre uma posição de memória em particular e a CPU ou entre dispositivos de E/S e a CPU. A única questão é, "qual é a posição de memória ou o dispositivo de E/S?". O barramento de endereços responde esta questão. Para diferenciar posições de memória de dispositivos de E/S, o projetista do sistema atribui um único endereço de memória para cada elemento de memória e para cada dispositivo de E/S. Quando o software quiser acessar alguma posição de memória ou um dispositivo de E/S em particular, ele coloca o endereço correspondente no barramento de endereços. Circuitos associados à memória ou ao dispositivo de E/S reconhecem este endereço e instruem a memória ou o dispositivo de E/S a ler o dado de ou para o barramento de dados. Em ambos os casos, todas as outras posições de memória ignoram a requisição. Apenas o dispositivo cujo endereço combina com o valor no barramento de endereço é que responde.
Com uma única linha de endereço, um processador poderia criar exatamente dois endereços únicos: zero e um. Com n linhas, o processador pode fornecer 2n endereços distintos (já que há 2n valores únicos num número binário de n bits). Portanto, é o número de bits no barramento de endereços que determina o número máximo de memória endereçável e de posições de E/S. O 8088 e o 8086, por exemplo, têm barramentos de endereços de 20 bits. Portanto, eles podem acessar até 1.048.576 (ou 220) posições de memória. Barramentos de endereços maiores podem acessar mais memória. O 8088 e o 8086 por exemplo, sofrem de anemia de espaço de endereços - seus barramentos de endereços são muito pequenos. Processadores mais recentes têm barramentos de endereços maiores:
Processador | Tamanho do Barramento de Dados | Máximo de Memória Endereçável | Unidade |
---|---|---|---|
8088 | 20 | 1.048.576 | 1 Megabyte |
8086 | 20 | 1.048.576 | 1 Megabyte |
80188 | 20 | 1.048.576 | 1 Megabyte |
80186 | 20 | 1.048.576 | 1 Megabyte |
80286 | 24 | 16.777.246 | 16 Megabytes |
80386SX | 24 | 16.777.246 | 16 Megabytes |
80386DX | 32 | 4.294.976.296 | 4 Gigabytes |
80486 | 32 | 4.294.976.296 | 4 Gigabytes |
80586 Pentium Pro | 32 | 4.294.976.296 | 4 Gigabytes |
Futuros processadores 80x86 provavelmente suportarão barramentos de endereços de 48 bits. Hoje em dia muitos programadores consideram quatro gigabytes de memória pouco (houve um tempo em que um megabyte foi considerado muito mais do que qualquer um poderia precisar!). Felizmente, a arquitetura do 80386, 80486 e chips mais novos permitem uma fácil expansão para barramentos de endereço de 48 bits através de segmentação.
O barramento de controle
O barramento de controle é uma coleção eclética de sinais que controlam a forma como o processador se comunica com o resto do sistema. Considere por um momento o barramento de dados. A CPU envia dados para a memória e recebe dados da memória através do barramento de dados. Isto gera a pergunta: ele está enviando ou recebendo? Há duas linhas no barramento de controle, a linha de leitura e a linha de escrita, que especificam a direção do fluxo de dados. Outros sinais incluem clocks do sistema, linhas de interrupção, linhas de status e assim por diante. A exata composição do barramento de controle depende do processador da família 80x86. Contudo, algumas linhas de controle são comuns a todos os processadores e valem um breve comentário.
As linhas de controle de leitura e escrita controlam a direção dos dados no barramento de dados. Quando ambas contém um 1 lógico, a CPU e a E/S da memória não estão se comunicando uma com a outra. Se a linha de leitura estiver baixa (zero lógico), a CPU está lendo dados da memória (isto é, o sistema está transferindo dados da memória para a CPU). Se a linha de escrita está baixa, o sistema transfere dados da CPU para a memória.
As linhas de controle de um byte são um outro conjunto importante de linhas de controle. Estas linhas de controle permitem que processadores de 16, 32 e 64 bits trabalhem com fragmentos menores de dados. Detalhes adicionais aparecerão na próxima seção.
A família 80x86, diferente de muitos outros processadores, fornece dois espaços de endereços distintos: um para memória e um para E/S. Enquanto os barramentos de endereços de memória nos vários processadores 80x86 variam de tamanho, o barramento de endereços de E/S é de 16 bits em todas as CPUs do 80x86. Isto permite que o processador enderece até 65.536 posições diferentes de E/S. Acontece que muitos dispositivos (como teclado, impressora, drives de disco, etc.) requerem mais do que uma posição de E/S. Apesar disto, 65.536 posições de E/S são mais do que suficientes para a maioria das aplicações. O projeto original do IBM PC permitia apenas o uso de 1.024 posições.
Embora a família 80x86 suporte dois espaços de endereço, ela não tem dois barramentos de dados (para E/S e memória). Ao invés disto, o sistema compartilha o barramento de endereço com os dois tipos endereços, de E/S e de memória. Linhas de controle adicionais decidem se o endereço é referente à memória ou à E/S. Quando tais sinais estão ativos, os dispositivos de E/S utilizam o endereço nos 16 bits menos significativos do barramento de endereços. Quando inativos, os dispositivos de E/S ignoram os sinais no barramento de endereços (o subsistema de memória assume a partir deste ponto).
:::: :::: O subsistema da memória ::::Um processador 80x86 típico endereça no máximo 2n posições diferentes de memória, onde n é o número de bits no barramento de endereços. Como você já viu, os processadores 80x86 têm barramentos de 20, 24 e 32 bits (com 48 bits a caminho).
É claro que a primeira pergunta que se poderia fazer é "O que exatamente é uma posição de memória?". O 80x86 permite memória endereçável por byte, portanto a unidade básica da memória é um byte. Então, com 20, 24 e 32 linhas de endereço, os processadores 80x86 podem endereçar um megabyte, 16 megabytes e quatro gigabytes de memória, respectivamente.
Pense na memória como um array linear de bytes. O endereço do primeiro byte é zero e o endereço do último byte é (2n)-1. Para um 8088, com um barramento de endereços de 20 bits, a seguinte declaração de array em pseudo-Pascal é uma boa aproximação do que é a memória:
Para executar o equivalente à instrução em Pascal "Memory[125] := 0;" a CPU coloca o valor zero no barramento de dados, o endereço 125 no barramento de endereços e ativa a linha de escrita (uma vez que a CPU está escrevendo dados na memória). Veja a Fig.2a.
Para executar o equivalente de "CPU := Memory[125];" a CPU coloca o endereço 125 no barramento de endereços, ativa a linha de leitura (já que a CPU está lendo dados da memória) e então lê o dado resultante do barramento de dados (Fig.2b).
A discussão acima aplica-se apenas para o acesso de um único byte na memória. Então, o que acontece quando o processador acessa um word ou um double word? Já que a memória consiste num array de bytes, como poderemos tratar valores maiores do que oito bits?
Diferentes sistemas têm diferentes soluções para este problema. A família 80x86 trata este problema armazenando o byte menos significativo de um word no endereço especificado e o byte mais significativo na próxima posição. Então, um word consome dois endereços de memória consecutivos (é o que se poderia esperar, já que um word tem dois bytes). Da mesma forma, um double word consome quatro posições de memória consecutivas. O endereço para o double word é o endereço do seu byte menos significativo. Os três bytes restantes seguem este byte menos significativo, com o byte mais significativo aparecendo no endereço do double word mais três.
Bytes, words e double words podem começar em qualquer endereço válido da memória. Veremos em breve, contudo, que iniciar grandes objetos em endereços arbitrários não e uma boa idéia.
Note que a probabilidade de que os valores de um byte, de um word e de um double word se sobreponham na memória é grande. Por exemplo, na Fig.3 poderíamos ter uma variável word começando no endereço 193, um byte no endereço 194 e um valor double word começando no endereço 192. Todas estas variáveis estariam sobrepostas.
Os microprocessadores 8088 e 80188 têm um barramento de dados de oito bits. Isto significa que a CPU pode transferir oito bits de dados por vez. Já que cada endereço de memória corresponde a um byte de oito bits, a melhor arquitetura (do ponto de vista de hardware), seria a da Fig.4, onde os dados vêm da memória 8 bits por vez.
O termo "array de memória endereçável por byte" significa que a CPU pode endereçar memória em fragmentos tão pequenos quanto um único byte. Também significa que esta é a menor unidade de memória que você pode acessar por vez com o processador. Isto é, se o processador quiser acessar um valor de quatro bits, ele deve ler oito bits e ignorar os quatro bits extras. Também significa que endereçabilidade por byte não implica que a CPU possa acessar oito bits sem qualquer tipo de limite. Quando especificamos o endereço 125 na memória, obtemos todos os oito bits daquele endereço, nada mais e nada menos. Endereços são inteiros; não podemos, por exemplo, especificar o endereço 125,5 para trazer menos do que oito bits.
Par | Ímpar |
---|---|
6 | 7 |
4 | 5 |
2 | 3 |
0 | 1 |
O 8088 e o 80188 podem manipular valores de words e double words, mesmo com seus barramentos de oito bits. Contudo, isto requer múltiplas operações de memória porque estes processadores podem apenas mover oito bits de dados por vez. Carregar um word requer duas operações na memória; carregar um double word requer quatro operações na memória.
Os processadores 8086, 80186, 80286 e 80386SX têm um barramento de dados de 16 bits. Isto permite que estes processadores acessem duas vezes mais memória na mesma quantidade de tempo que seus irmãos de oito bits. Estes processadores organizam a memória em dois bancos: um banco "par" e um banco "ímpar".
A Fig.5 ilustra a conexão à CPU (D0-D7 identifica o byte menos significativo do barramento de dados e D8-D15 identifica o byte mais significativo do barramento de dados).
Os membros de 16 bits da família 80x86 podem carregar um word de qualquer endereço arbitrário. Como mencionado anteriormente, o processador busca o byte menos significativo do valor no endereço especificado e o byte mais significativo no endereço seguinte. Isto cria um pequeno problema se analisarmos corretamente o diagrama da Fig.5. O que acontece quando acessamos um word num endereço ímpar? Suponha que você queira ler um word na posição 125. O byte menos significativo vem da posição 125 e o byte mais significativo vem da posição 126. O que acontece? Há dois problemas neste caso.
As linhas 8 a 15 do barramento de dados (o byte mais significativo) estão no banco ímpar e as linhas 0 a 7 do barramento de dados (o byte menos significativo) estão no banco par. Acessar a posição 125 da memória transferirá dados para a CPU do byte mais significativo do barramento de dados; mas queremos este dado no byte menos significativo! Felizmente, as CPUs do 80x86 reconhecem esta situação e automaticamente transferem os dados em D8-D15 para o byte menos significativo.
O segundo problema é ainda mais obscuro. Quando acessamos words, na realidade estamos acessando dois bytes separados, cada um dos quais tem seu próprio endereço de byte. Então surge a questão: "Que endereço aparece no barramento de dados?". As CPUs de 16 bits do 80x86 sempre colocam endereços pares no barramento de dados. Os bytes pares sempre aparecem nas linhas de dados D0-D7 e os bytes ímpares sempre aparecem nas linhas de dados D8-D15. Se acessarmos um word num endereço par, a CPU pode trazer um fragmento inteiro de 16 bits numa operação de memória. Da mesma forma, se você acessar um único byte, a CPU ativa o banco apropriado (utilizando as linhas de controle). Se o byte estiver num endereço ímpar, a CPU automaticamente o moverá do byte mais significativo no barramento para o byte menos significativo.
Então, o que acontece quando a CPU acessa um word num endereço ímpar, como no exemplo dado anteriormente? Bem, a CPU não pode colocar o endereço 125 no barramento de endereços e ler os 16 bits da memória. Não há endereços ímpares resultantes de uma CPU de 16 bits do 80x86. Os endereços são sempre pares. Portanto, se tentarmos colocar 125 no barramento de endereços, o que será colocado será 124. Se lermos os 16 bits neste endereço, obteremos o word do endereço 124 (byte menos significativo) e 125 (mais significativo) - e não o que esperávamos. Para acessar um word num endereço ímpar é preciso ler o byte do endereço 126. Finalmente, deve-se trocar as posições destes bytes internamente, uma vez que ambos entraram na CPU na metade errada do barramento de dados.
Felizmente as CPUs de 16 bits do 80x86 ocultam estes detalhes. Seus programas podem acessar words em qualquer endereço e a CPU acessará apropriadamente e trocará (se necessário) os dados na memória. Contudo, acessar um word num endereço ímpar requer duas operações a mais na memória (exatamente como o 8088/80188). Portanto, acessar words em endereços ímpares num processador de 16 bits é mais lento do que acessar words em endereços pares. Organizando cuidadosamente a utilização da memória você pode dar mais velocidade ao seu programa.
Em processadores de 16 bits, acessar quantidades de 32 bits sempre precisam, no mínimo, de duas operações de acesso à memória. Se você acessar 32 bits em endereços ímpares, o processador exigirá três operações de memória para acessar o dado.
Os processadores de 32 bits do 80x86 (o 80386, 80486 e o Pentium Overdrive) utilizam quatro bancos de memória conectados ao barramento de dados de 32 bits.
O endereço colocado no barramento de endereços é sempre um múltiplo de quatro. Utilizando várias linhas com capacidade de um byte, a CPU pode selecionar quais dos quatro bytes daquele endereço o software quer acessar. Assim como nos processadores de 16 bits, a CPU automaticamente rearranjará os bytes quando necessário.
Com a interface de memória de 32 bits, a CPU do 80x86 pode acessar qualquer byte com uma única operação de memória. Se não for igual a três (endereço MOD 4), então uma CPU de 32 bits pode acessar um word em qualquer endereço utilizando uma única operação na memória. Contudo, se o resto for três, então ela gastará duas operações de memória para acessar o referido word.
Este é o mesmo problema encontrado no processador de 16 bits, exceto por ele ocorrer com a metade da frequência.
Uma CPU de 32 bits pode acessar um double word com uma única operação de memória se o endereço daquele valor for exatamente divisível por quatro. Se não, a CPU necessitará de duas operações de memória.
Uma vez mais a CPU gerencia tudo automaticamente. Contudo, há o benefício da performance se os dados forem alinhados adequadamente. Como regra geral, deve-se sempre colocar valores de words em endereços pares e valores de double words em endereços que são exatamente divisíveis por quatro. Isto tornará o programa mais rápido.
:::: :::: O subsistema de entrada e saída (E/S) ::::Além das 20, 24 ou 32 linhas de endereço que acessam a memória, a família 80x86 fornece um barramento de endereços de E/S de 16 bits. Isto dá às CPUs do 80x86 dois espaços de endereços separados: um para memória e um para operações de E/S. As linhas do barramento de controle diferenciam os endereços de memória e os de E/S. Exceto por linhas de controle separadas e por um barramento menor, acessos à E/S comportam-se exatamente como acessos à memória. Memória e dispositivos de E/S compartilham o mesmo barramento de dados e as 16 linhas menos significativas do barramento de endereços.
Há três limitações no subsistema de E/S do IBM PC. Primeiro, as CPUs do 80x86 requerem instruções especiais para acessar dispositivos de E/S; segundo, os projetistas do IBM PC usaram as "melhores" posições de E/S para atender interesses próprios, forçando outros desenvolvedores a utilizarem as posições de memória menos acessíveis; terceiro, os sistemas 80x86 não podem endereçar mais do que 65.536 (216) endereços de E/S. Quando se considera que uma placa de vídeo VGA típica requer mais de 128.000 posições diferentes, pode-se vislumbrar um problema com o tamanho do barramento de E/S.
Felizmente desenvolvedores de hardware podem mapear seus dispositivos de E/S para o espaço de endereçamento da memória tão facilmente quanto para o espaço de endereçamento de E/S. Então, utilizando o sistema de circuitos apropriados, podem fazer seus dispositivos de E/S se parecerem exatamente com a memória. É como, por exemplo, os adaptadores de vídeo no IBM PC funcionam.
Acessar dispositivos de E/S é um assunto ao qual retornaremos mais adiante. Por enquanto assumiremos que acessos à E/S e à memória funcionam da mesma forma.
:::: {/faqslider}Fonte
- Art of Assembly de Randall Hyde.
- Tradução meio que livre da vovó Vicki.