Arquitetura de Computadores
© Todos os direitos reservados. Nenhuma parte desta obra pode ser reproduzida ou transmitida por qualquer forma e/ou quaisquer meios (eletrônico, incluindo fotocópia e gravação) ou arquivada em qualquer sistema ou banco de dados sem permissão escrita da Universidade Paulista.
APRESENTAÇÃO APRESENT AÇÃO 1. Apresentação da Disciplina: Esta disciplina visa a conceituar a organização e arquitetura de computadores e máquinas multiníveis, a organização de sistemas computacionais e seus elementos principais, tais como CPU, memória, entradas e saídas, elementos multimídia e barramentos. Apresentar o nível lógico digital: unidade lógica e aritmética, a organização da memória, clock e registradores. No nível da microarquitetura, serão apresentados os caminhos de dados, a temporização dos d os caminhos de dados, a operação da memória memór ia e as microinstruções. Exemplos de macroarquitetura e projeto do nível de microarquitetura.
2. Objetivos Gerais Fornecer o suporte para que o aluno tome contato com as técnicas de projeto de um sistema computacional.
3. Objetivos Específicos Fornecer o suporte para o entendimento de sistemas computacionais tanto do ponto de vista do software quanto do hardware.
4. Plano de Ensino CURSO: Ciência da Computação SÉRIE: 5o semestre DISCIPLINA: Arquitetura de Computadores CARGA HORÁRIA SEMANAL: 02 horas-aula CARGA HORÁRIA SEMESTRAL: 40 horas-aula I – EMENTA Conceituação de Organização e Arquitetura de Computadores e Máquinas Multiníveis. Organização de Sistemas Computacionais: CPU, Memória, Entradas e Saídas, Multimídia e Barramentos. Nível da Microarquitetura: Fluxos de Dados, Temporização do Fluxo de Dados, Operação de Memória, Microinstruções. II – OBJETIVOS GERAIS Fornecer o suporte para que o aluno tome contato com as técnicas de projeto de um sistema computacional. 3
III – OBJETIVOS ESPECÍFICOS
Fornecer o suporte para o entendimento de sistemas computacionais tanto do ponto de vista do software quanto do hardware . IV – CONTEÚDO PROGRAMÁTICO 1. Organização estruturada de computadores – Máquinas multiníveis contemporâneas: nível da lógica digital. 2. Organização estruturada de computadores – Máquinas multiníveis contemporâneas: nível da microarquitetura. 3. Organização estruturada de computadores – Máquinas multiníveis contemporâneas: nível da arquitetura do conjunto de instruções. 4. Organização estruturada de computadores – Máquinas multiníveis contemporâneas: nível de máquina do sistema operacional. 5. Organização estruturada de computadores – Máquinas multiníveis contemporâneas: nível de linguagem de montagem. 6. Organização de sistemas computacionais – Processadores: organização da CPU; execução de instruções primárias: endereços, ordenação dos bytes , códigos de correção de erros. 7. Organização de sistemas computacionais – Processadores: princípios de projeto para computadores modernos, paralelismo no nível de instrução, paralelismo no nível de processador. 8. Organização de sistemas computacionais – Memória primária: endereços, ordenação dos bytes , códigos de correção de erros (bit de paridade e código de Hamming). 9. Organização de sistemas computacionais – Memória secundária – dispositivos de armazenamento: HDs (IDE, EIDE, SCSI, RAID). 10. Organização de sistemas computacionais – Memória secundária – dispositivos de armazenamento: CDs; DVDs. 11. Organização de sistemas computacionais – Entrada e Saída: barramentos. 12. Nível de microarquitetura (microprogramação) – Exemplo de microarquitetura de ULA: fluxo de dados, temporização do fluxo de dados.
4
V – ESTRATÉGIA DE TRABALHO Aulas expositivas e recursos audiovisuais. VI – AVALIAÇÃO Provas bimestrais. VII – BIBLIOGRAFIA Básica HENNESSY, John L.; PATTERSON, D. A. “Organização e Projeto de Computadores”. 3. ed. 2005. Editora Campus. MONTEIRO, M. A. “Introdução à organização de computadores”. Rio de Janeiro: LTC, 2001. TANENBAUM, A. S. “Organização estruturada de computadores”. 4. ed. Rio de Janeiro: LTC, 2001. Complementar DELGADO, J.; RIBEIRO, C. “Arquitetura de Computadores”. Editora LTC, 2009. MURDOCCA, M. “Introdução à Arquitetura de Computadores”. Ed. Campus, 2001. PARHAMI, B. “Arquitetura de Computadores”. Ed. Mcgraw-hill Interamericana, 2008. STALLINGS, W. “Arquitetura e organização de computadores”. Ed. Prentice-Hall, 2010. WEBER, R. F. “Fundamentos de Arquitetura de Computadores”. 3. ed. Vol. 8, Ed Artmed, 2008.
5
ARQUITETURA DE COMPUTADORES
Unidade I ORGANIZAÇÃO ESTRUTURADA DE COMPUTADOR (PARTE 1) Estrutura de um Computador Em primeiro lugar, vamos definir quais devem ser os componentes básicos que definem um computador. Um computador é uma máquina de processar informações, para tanto, precisa de um processador lógico, cuja função é realizar operações funcionais sobre dados de entrada, devolvendo dados de saída. De nada adiantaria haver capacidade de processamento sem uma memória que armazene dados. Não é possível haver processamento sem uma memória para armazenar os dados de entrada, os dados de saída, ou os dados que estão sendo processados. Também é necessário haver comunicação com o mundo externo, por onde os dados de entrada são inseridos, ou por onde os dados de saída podem ser exibidos ao operador humano ou ainda enviados a outro dispositivo. Tais componentes constituem os periféricos de E/S (E/S = Entrada e Saída, ou I/O = Input/Output). Processador, Memória(s) e Periféricos precisam naturalmente comunicar-se entre si, permitindo que dados sejam enviados, por exemplo, da memória para o processador ou vice-versa. Essa comunicação interna é realizada por um sistema de barramentos. Qualquer dispositivo programável cuja estrutura seja a da figura abaixo pode ser considerado um computador. Desde um supercomputador de milhões de dólares a um chip microcontrolador que custa centavos de dólar.
7
Unidade I
Computador
Memória
Periféricos
Barramentos
Processador
MÁQUINAS MULTINÍVEIS Conteúdo programático: Máquinas multiníveis: nível da lógica digital, nível de microarquitetura e nível de arquitetura de conjunto de instruções. Os computadores atuais são compostos por circuitos eletrônicos digitais. Tais circuitos baseiam-se em um componente eletrônico relativamente simples chamado transistor. O transistor opera basicamente como uma chave digital, por onde uma corrente elétrica pode passar ou não. Com esses dois estados possíveis, pode-se implementar circuitos que realizam operações lógicas binárias. É natural pensar que, quanto mais complexas as operações realizadas pelo processador de um computador, mais complexos devem ser seus circuitos internos. Complexidade, geralmente, significa alto custo (elevado número de componentes) e baixa confiabilidade (elevado número de pontos onde falhas podem ocorrer). Portanto, as operações que as instruções que uma CPU pode realizar, geralmente, são bem simples. Operações elementares como “some dois números” ou “carregar um dado presente na memória”. Ou seja, a linguagem da máquina é composta por instruções bem elementares. Um programa de computador, por mais complexa a tarefa que realiza, é composto por um número elevado dessas instruções simples na sequência apropriada. O programa nada mais é do que uma sequência de passos elementares que, implementados de uma forma correta, levam à execução das tarefas muitas vezes bem complexas. É claro que, se a tarefa a ser realizada é complexa e as instruções disponíveis são bem simples, um programa acaba possuindo um grande número de instruções. Isso torna o fato de se programar em tais linguagens uma tarefa razoavelmente penosa para programadores humanos. Além é claro do fato de os dados estarem representados na forma digital binária. 8
ARQUITETURA DE COMPUTADORES
A maioria dos microprocessadores possui um “vocabulário” bem restrito de instruções. Ao contrário da linguagem humana, que possui um amplo vocabulário. Já que um programa é constituído por uma grande sequência de instruções simples, e as instruções estão na forma binária, a programação em linguagem de máquina é trabalhosa, complexa e propensa a erros. Criar um computador cujo hardware é capaz de processar instruções mais complexas (uma linguagem mais próxima da humana), por outro lado, é economicamente inviável. A solução encontrada pelos projetistas foi criar uma estrutura de camadas ou níveis de linguagens em que os níveis mais baixos possuem uma linguagem mais próxima da máquina, e os níveis mais altos, uma linguagem mais apropriada para seres humanos. A tarefa de programar torna-se mais fácil e mais produtiva. Os programas criados em linguagens de alto nível são traduzidos ou interpretados para a linguagem do nível inferior. Cada nível possui sua linguagem própria, que deve ser traduzida ou interpretada para o nível inferior, até que no nível mais baixo temos as operações que são realizadas diretamente pelo hardware baseado em eletrônica digital. A grande maioria dos computadores atuais é constituída de dois ou mais níveis, podendo atingir até seis níveis, como apresentado na figura 1. Nível 4
Nível das linguagens orientadas para a solução de problemas Tradução (compilador)
Nível 4
Nível da linguagem do montador Tradução (montador)
Nível 3
Nível do sistema operacional Interpretação parcial (sist. operacional)
Nível 2
Nível da arquitetura do conjunto de instruções Interpretação ou execução direta (microprograma)
Nível 1
Nível da microarquitetura Hardware
Nível 0
Nível da lógica digital Figura 1 – Computador com seis níveis
9
Unidade I
NÍVEL DE LÓGICA DIGITAL O nível mais baixo (nível 0), ou nível de lógica digital, é composto pelo hardware da máquina. Seus circuitos executam programas na linguagem do nível 1. Os elementos de interesse desse nível são conhecidos como portas lógicas. Apesar de constituídas por elementos analógicos como transistores, as portas lógicas podem ser modeladas como dispositivos digitais. Cada porta lógica tem uma ou mais entradas digitais (sinais que representam os valores lógicos 0 ou 1) e calcula algumas funções bastante simples sobre essas entradas, como AND (E) e OR (OU) e NOT (NEGAÇÃO), ou seja, as operações básicas da álgebra booleana. Cada porta lógica é construída a partir de um conjunto de transistores. Certa quantidade dessas portas pode ser combinada de modo a formar, por exemplo, uma memória de 1 bit, dispositivo capaz de armazenar o valor 0 ou o valor 1. Tais dispositivos com capacidade de armazenar um bit de informação são, muitas vezes, denominados latch ou flip-flop. Memórias de 1 bit podem ser combinadas em grupos de maneira a formar, por exemplo, registradores de 16, 32 ou 64 bits. Cada registrador pode guardar uma única sequência de bits, até um dado valor máximo. Em resumo, as portas lógicas podem ser combinadas para formar o principal dispositivo de um sistema computacional, o processador.
Obs.: Quando dizemos que um dado processador é de 8, 16, 32 ou 64 bits, geralmente, estamos nos referindo ao número de flip-flops de seus registradores internos. O nível de lógica digital é o mais primitivo. Como constitui o hardware básico de qualquer computador digital, mesmo os primeiros computadores possuíam esse nível. É a eletrônica que compõe a máquina física. Existe um nível ainda mais baixo, quando consideramos os transistores que compõem as portas lógicas. Portanto, o nível inferior à lógica digital é a Microeletrônica. Um nível ainda mais baixo estuda como os transistores dos microcircuitos funcionam. Esse nível é a Física do Estado Sólido.
NÍVEL DE MICROARQUITETURA No nível de microarquitetura encontra-se um conjunto de 8 a 32 registradores que formam a memória local e também um circuito denominado ULA (Unidade Lógica e Aritmética) que é capaz de realizar operações aritméticas simples. Os registradores são conectados à ULA, formando o caminho de dados, por onde os dados transitam. Tais caminhos de dados são os barramentos internos do processador. Esse nível também define se as instruções em linguagem de máquina são interpretadas como microprogramas (processadores CISC), ou se são executadas diretamente pelo hardware (processadores RISC). O nível de microarquitetura também estuda os registradores necessários para a operação do processador. Muitos desses registradores são invisíveis ou transparentes para o nível ISA. O programador 10
ARQUITETURA DE COMPUTADORES
não possui acesso a eles. Por exemplo, é necessário um registrador para endereçar as instruções que são buscadas na memória durante a execução dos programas. Um outro registrador é necessário para armazenar a instrução que foi buscada na memória, para que seja decodificada e, em seguida, executada. Essas operações devem ocorrer independentemente do que é programado nas instruções da máquina. Fazem parte do projeto do microprocessador e funcionam da mesma maneira qualquer que seja a instrução executada.
NÍVEL DO CONJUNTO DE INSTRUÇÕES DA MÁQUINA (ISA) O nível 2 é denominado nível da arquitetura do conjunto de instruções (ou nível ISA – Instruction Set Architecture). Esse nível contém o conjunto de instruções que são executadas por meio de microprogramação (no caso de processadores CISC) ou diretamente pelo hardware da máquina (processadores RISC). O nível ISA estabelece o formato e o tamanho em bits das instruções, o número de ciclos de clock que cada instrução consome e o número de instruções presentes no processador, bem como o tamanho em bits e os tipos de dados manipulados pelas instruções. Define, por exemplo, se um processador possui uma instrução de divisão, ou se será necessário desenvolver uma rotina com instruções de subtração criada por um programador para realizar uma operação de divisão.
BIBLIOGRAFIA ENGLANDER, I. “A Arquitetura de Hardware Computacional, Software de Sistema e Comunicação em Rede”. 4. ed. Rio de Janeiro: LTC, 2011 TANENBAUM, A. S. “Organização estruturada de computadores”. 5. ed. São Paulo: Pearson: Prentice Hall, 2007. WEBER, R. F. “Fundamentos de Arquitetura de Computadores”. 4. ed. Porto Alegre: Bookman, 2012. Organização Estruturada de Computador (parte 2)
MÁQUINAS MULTINÍVEIS – CONTINUAÇÃO Máquinas multiníveis: nível de máquina de sistema operacional, nível de linguagem de montador e nível de linguagem orientada a problema. O nível 3 é denominado nível do sistema operacional. Um sistema operacional é um programa que adiciona um conjunto de novas instruções e funcionalidades, além daquelas suportadas pelo nível ISA. O conjunto de instruções do nível do sistema operacional é aquele que está disponível para os programadores de aplicações. Nele estão presentes praticamente todas as instruções do nível ISA, bem como um novo conjunto de instruções que o sistema operacional adiciona, conhecido como chamadas de sistema. 11
Unidade I
Uma chamada de sistema ativa um determinado serviço prestado pelo sistema operacional ao nível da aplicação, como a leitura de um dado de um arquivo. O nível do sistema operacional é sempre interpretado, ou seja, quando um programa do usuário executa uma instrução desse nível, o sistema operacional executa essa instrução passo a passo. Outra funcionalidade importante do nível do sistema operacional é a abstração do hardware. A parte física de uma máquina (hardware) pode ser bem diferente do de outra máquina. Os sinais digitais necessários para executar uma mesma tarefa podem ser radicalmente diferentes de um modelo de computador para cada dispositivo poder trabalhar com uma linguagem específica. Entretanto, deve ser possível que um mesmo programa rode adequadamente em dois computadores com diferentes estruturas de hardware. É aí que entra o Sistema Operacional. Ele é um programa especial capaz de gerenciar o funcionamento de todos os outros, realizando a interpretação entre a linguagem genérica do software para a linguagem mais específica do hardware. Por exemplo, todos os programas compatíveis com um dado sistema operacional podem invocar as mesmas instruções na forma de chamadas de sistema para escrever um arquivo em um disco. Cabe ao sistema operacional interpretar essa chamada de sistema e executá-la, comunicando-se com o hardware onde o arquivo será gravado. Esse hardware pode ser um disco rígido ou um pen-drive, por exemplo. Ambos possuem uma tecnologia totalmente diferente e cabe ao sistema operacional ser capaz de se comunicar adequadamente com o dispositivo em questão. Por exemplo, no caso de dispositivos plug and play com interface de comunicação USB como um pen-drive ou HD externo, quando são plugados em um computador pela primeira vez, surge uma mensagem de instalação do driver do dispositivo. Instalar o driver de um novo periférico é a maneira do sistema operacional “aprender” uma nova linguagem, para comunicar-se com um novo dispositivo. O sistema operacional também encarrega-se do gerenciamento de processos e da hierarquia de acesso dos processos em execução. Pode-se ter um sistema operacional multitarefa, com cada processo em execução por uma fatia de tempo, determinado pelo s.o. Os processos também não podem ter acesso a qualquer endereço de memória, pois dessa maneira poderiam provocar pane em outros processos ou no funcionamento do próprio sistema operacional. O acesso à memória é restrito, pois processos comuns são executados com o microprocessador no modo protegido. Aspectos importantes relativos aos sistemas operacionais: memória virtual, entrada/saída de arquivos e processamento paralelo. Memória virtual é uma técnica implementada na maioria dos sistemas operacionais para fazer com que a máquina pareça ter mais memória do que na verdade ela tem. 12
ARQUITETURA DE COMPUTADORES
Uma maneira de se organizar a memória virtual é usar uma abstração denominada arquivo. Para o sistema operacional, um arquivo nada mais é do que uma sequência de bytes. A E/S de arquivos é feita por chamadas do sistema operacional para abertura, leitura, escrita e fechamento de arquivos. Em um sistema computacional com mais de um processador, cada um dos vários processos cooperantes que rodam nele poderá ter seu próprio processador, de modo a permitir que esses processos avancem simultaneamente. Por outro lado, se houver apenas um processador disponível, o efeito do processamento paralelo poderá ser simulado, fazendo com que o processador se dedique a um processo de cada vez, por curto espaço de tempo, ou seja, o processador pode ser compartilhado por vários processos. O nível 4 é denominado nível de linguagem de montagem (assembly language). Neste nível ocorre a tradução do programa original, expresso na linguagem fonte para uma outra linguagem denominada linguagem alvo. Dependendo da relação entre a linguagem fonte e a linguagem alvo, os tradutores podem ser divididos em dois grupos. Quando a linguagem fonte for essencialmente uma representação simbólica para uma linguagem de máquina numérica, o tradutor é chamado de montador (assembler) e a linguagem fonte é chamada de linguagem de montagem (assembly). Por outro lado, quando a linguagem fonte for uma linguagem de alto nível e a linguagem alvo for uma linguagem de máquina numérica ou uma representação simbólica dessa linguagem, o tradutor é chamado de compilador. Uma linguagem de montagem pura é aquela na qual cada comando produz exatamente uma instrução de máquina, ou seja, existe uma correspondência um para um entre as instruções de máquina e os comandos de um programa expresso em linguagem do montador. As linguagens do nível 5 são projetadas para serem usadas por programadores de aplicação, com algum problema a ser resolvido. Tais linguagens são conhecidas como linguagens de alto nível. Os programas escritos nessas linguagens são convertidos para os níveis 3 ou 4 por tradutores conhecidos como compiladores. Exemplo de um programa simples para imprimir uma mensagem na tela: Usando uma linguagem do nível 5 (linguagem C): #include int main( int argc, char *argv[] ) { 13
Unidade I
printf( “Olá, mundo!” ); return 0; } E na linguagem do nível 4 (assembly ou linguagem de montagem para processadores da família x86 com sistema operacional Windows ou MS-DOS): .model tiny .data DB frase ‘Olá, mundo!”, $ .code org
0100h
mov dx, frase mov ah, 9
int
21h
mov ah, 4ch
int
21h
.end Outro exemplo de trecho de código escrito em assembly para processadores da família x86 (presente em computadores pessoais). ; ------------- Início da manipulação dos dados do arquivo encontrado ;
14
----- Abre o arquivo, obtendo o Handle mov dx, 9eh
; Endereço onde está o nome do arquivo encontrado.
mov ax, 3d02h int 21h
; Abre o arquivo para leitura-escrita.
ARQUITETURA DE COMPUTADORES
; O handle do arquivo foi obtido em AX mas deve ; ser movido para BX para as próximas funções.
mov bx, ax ;
----- Obtém a data e hora da última alteração do arquivo. mov ah, 57h xor al, al ; int 21h
mov al,
0
lea di, [offset Horario + bp] mov ax, cx stosw lea di, [offset Data + bp] mov ax, dx stosw
; ; ; ;
----- Salva a parte do arquivo que inevitavelmente será alterada, lendo e armazenando os primeiros bytes do arquivo a ser modificado. Para tanto o início do futuro hospedeiro deve ser lido e os primeiros bytes armazenados em Backup. lea mov mov int
dx, [offset Backup + bp] cx, bytes ah, 3fh 21h
; Buffer onde os dados serão gravados.
; ----- Descobre se o programa realmente é um .COM internamente
lea si, [offset Backup + bp] lodsw cmp ax, ‘ZM’ ; Equivale a comparar com ‘MZ’ je Proximo1
A linguagem assembly ainda é utilizada, principalmente, na programação de microcontroladores, que são computadores completos em um único chip, já que possuem processador, memória e periféricos embutidos. Circuitos eletrônicos com microcontroladores fazem parte dos chamados sistemas embarcados, que são sistemas que possuem microcontroladores que conferem certa “inteligência” a outros dispositivos, tais como eletrodomésticos, alarmes, fontes de energia, cancelas eletrônicas, brinquedos etc.
15
Unidade I
A seguir um exemplo de trecho de código escrito em assembly para um microcontrolador da família 8051. ORG 0000h ; VETOR DE RESET. SJMP STARTUP ; DESVIA PARA O CÓDIGO DE INICIALIZAÇÃO. ORG 0003h NOP RETI
; ENDEREÇO DA INT0.
ORG 000Bh NOP RETI
; ENDEREÇO DO TIMER0
ORG 0013h NOP RETI
; ENDEREÇO DA INT1.
ORG 001Bh NOP RETI
; ENDEREÇO DO TIMER1.
ORG 0023h NOP
; ENDEREÇO DA INTERRUPÇÃO SERIAL.
SJMP SERIALISR ; DESVIA PARA A ISR DA SERIAL. RETI STARTUP:
; CÓDIGO DE INICIALIZAÇÃO.
MOV P1, #00000000b
; PORT P1 INICIALMENTE ZERADO.
MOV TMOD, #00100000b
; TIMER1 EM MODO 2 : 8 BITS COM AUTO-RELOAD.
MOV TH1, #0FDh ; BAUD-RATE= 9600 bps MOV TL1, #0h
; PRESET VALUE DO MODO 2 DO TIMER1. ; CONTADOR INICIALMENTE EM ZERO.
SETB TR1; LIGA O TIMER1.
16
MOV SCON, #01010000b
; SERIAL NO MODO 1, COM BIT REN HABILITADO.
MOV PCON, #00000000b
; SMOD= 0. SEM DOBRAR A FREQUÊNCIA DA SERIAL.
ARQUITETURA DE COMPUTADORES
MOV IP, #00010000b
; INTERRUPÇÃO SERIAL COM ALTA PRIORIDADE.
MOV IE, #10010000b
; INTERRUPÇÃO SERIAL HABILITADA. COM EA= 1.
MAINLOOP:
; LAÇO PRINCIPAL DO PROGRAMA.
NOP SJMP MAINLOOP SERIALISR:
; LAÇO INFINITO. ; ROTINA DE TRATAMENTO DA INTERRUPÇÃO SERIAL.
NOP MOV P1, SBUF CLR RI
; MOVE O VALOR DO BUFFER SERIAL PARA O PORT P1. ; RESSETA O FLAG DA INTERRUPÇÃO DA SERIAL.
RETI
; RETORNO DA INTERRUPÇÃO.
END
; FIM DO PROGRAMA.
A seguir, outro exemplo de programação em assembly: um trecho de código para um microcontrolador da família HC908Q da Freescale: (Repare o que é escrito à direita do ponto e vírgula são comentários que servem apenas para o programador ter mais facilidade para entender o programa durante a edição do código, e não faz parte do código em linguagem de máquina gerado posteriormente). SHOWDISPLAY: MOV ,X+, DIGITO DIGITO, INCREMENTANDO X EM SEGUIDA. STX XBKP REGISTRADOR SERÁ ALTERADO.
; MOVE O VALOR APONTADO POR X PARA A VARIÁVEL
LDA #DISPLAY DOS DÍGITOS PARA DISPLAY. ADD DIGITO ÍNDICE.
; CARREGA O ENDEREÇO INICIAL DO VETOR DE CÓDIGO
TAX REGISTRADOR APONTADOR, X.
; SALVA O CONTEÚDO DE X EM XBKP, POIS ESSE
; ADICIONA O VALOR DO DÍGITO, QUE FUNCIONA COMO ; MOVE O RESULTADO, NO ACUMULADOR, PARA O
17
Unidade I
MOV ,X+, PTB ; MOVE O CONTEÚDO DO ENDEREÇO APONTADO POR X PARA O PORT PTB, EXIBINDO O DÍGITO NO DISPLAY. RTS
; RETORNO DA SUB-ROTINA.
TRATA_TIM: TIM ).
; ROTINA DE TRATAMENTO DA INTERRUPÇÃO DO TIMER (
LDA CONTADOR REGISTRADOR ACUMULADOR. BEQ PROSSEGUIR A ZERO.
; CARREGA O CONTEÚDO DA VARIÁVEL CONTADOR NO ; DESVIA PARA PROSSEGUIR, CASO O VALOR SEJA IGUAL
DEC CONTADOR
; SENÃO, DECREMENTA O CONTADOR.
BCLR 7, TSC
; RESSETA O FLAG DA INTERRUPÇÃO. T0F= 0.
RTI
; RETORNA DA ROTINA DE INTERRUPÇÃO.
PROSSEGUIR: BCLR 7, TSC
; RESSETA O FLAG DA INTERRUPÇÃO. TOF= 0.
LDA #$01 EOR PTA
; CARREGA A MÁSCARA 00000001 NO ACUMULADOR. ; REALIZA UMA OPERAÇÃO XOR, QUE INVERTE APENAS O
STA PTA
; CARREGA O RESULTADO NO PTA, PARA COMUTAR O
LDA TEMPO1 CMP #2
; CARREGA O CONTEÚDO DE TEMPO1 NO ACUMULADOR. ; COMPARA O VALOR COM 2.
BHI NAO_APAGAR
; SE MAIOR QUE 2, DESVIA PARA NAO_APAGAR.
BIT 0. LED.
CLR PTB DÍGITO SEGUINTE.
; APAGA O DISPLAY, TEMPORARIAMENTE, ANTES DO
NAO_APAGAR: DBNZ TEMPO1, NO_CHANGE ; DECREMENTA TEMPO1, DESVIANDO PARA NO_CHANGE SE DIFERENTE DE ZERO. MOV #6, TEMPO1 18
; REINICIA TEMPO1.
ARQUITETURA DE COMPUTADORES
Para exemplificar como a linguagem assembly muda de acordo com a arquitetura do processador, segue outro trecho de código escrito em assembly. Dessa vez, para um microcontrolador da família PIC16: RST GOTO ISR
CODE 0x0000
; VETOR DE RESET
STARTUP
; DESVIA PARA O CÓDIGO DE INICIALIZAÇÃO.
CODE 0x00004
; VETOR DE INTERRUPÇÃO.
MOVWF W_TEMP PRINCIPAIS. SWAPF STATUS, W BCF STATUS, RP0 MOVWF STATUS_TEMP
; SALVA A IMAGEM DOS REGISTRADORES
BTFSS TIMER0. GOTO
; TESTA SE A INTERRUPÇÃO FOI GERADA PELO
BCF
INTCON,
T0IF
RESTORE_REGS
;
INTCON,
; RESSETA BIT QUE SINALIZA A INTERRUPÇÃO.
T0IF
INCF DELAY_COUNT, MOVLW D’3’ SUBWF DELAY_COUNT, BNZ RESTORE_REGS INTERRUPÇÃO. CLRF
F
; INCREMENTA O CONTADOR DE ATRASO.
W
; APÓS 3 ITERAÇÕES VOLTA. ; ENQUANTO DELAY_COUNT != 3, RETORNA DA
DELAY_COUNT
INCF CONTADOR, CONTADOR + 1.)
; RESSETA O CONTADOR DELAY_COUNT. F
; INCREMENTA O CONTADOR. ( CONTADOR=
MOVLW D’100’ SUBWF CONTADOR, W BNC RESTORE_REGS CLRF CONTADOR
; SE CONTADOR == 100, CONTADOR= 0.
RESTORE_REGS
; RESTAURA OS REGISTRADORES WREG E STATUS.
SWAPF STATUS_TEMP, MOVWF STATUS
W 19
Unidade I
SWAPF W_TEMP, SWAPF W_TEMP,
F W
RETFIE
; RETORNA DA INTERRUPÇÃO.
STARTUP CODE
; CÓDIGO DE INICIALIZAÇÃO.
STARTUP BANK1 MOVLW B’00000111’ MOVWF OPTION_REG
; TIMER0 COM PRESCALER 1:128.
CLRF
TRISB
; TODOS OS PINOS DO PORTB FUNCIONAM COMO SAÍDAS.
DELAY_COUNT
; INICIALIZA DELAY_COUNT ZERADO.
BANK0 CLRF
MOVLW B’10100000’ MOVWF INTCON
; HABILITA A CHAVE GERAL DE INTERRUPÇÕES E A INT. ; DO TIMER0.
CLRF
; RESSETA O CONTADOR.
CONTADOR
MOVLW D’10’ MOVWF DIVISOR
; DIVISOR= 10.
CLRF
; RESSETA O PORTB.
PORTB
MAINLOOP MOVF CONTADOR, MOVWF DIVIDENDO CALL
DIVISAO
SWAPF QUOCIENTE, IORWF RESTO, MOVWF PORTB
20
W
; DIVIDENDO= CONTADOR. ; CHAMA A ROTINA DE DIVISÃO.
W W
GOTO
MAINLOOP
END
; FIM DO PROGRAMA.
; CARREGA EM WREG QUOCIENTE COM OS NIBBLES TROCADOS. ; ATRIBUI RESTO AO NIBBLE MENOS SIGNIFICATIVO. ; CONTEÚDO NA SAÍDA DO PORTB. ; PERMANECE NO LAÇO MAINLOOP.
ARQUITETURA DE COMPUTADORES
Naturalmente, é bem mais fácil programar em assembly do que diretamente em código de linguagem de máquina (os primeiros computadores eram programados em linguagem de máquina binária). Entretanto, mais fácil é programar em linguagens de médio e alto nível, tais como as linguagens descendentes de Basic, C e Pascal. Essas linguagens estão estruturadas de uma forma mais próxima da descrição de um algoritmo e mais distantes da linguagem da máquina. É fácil perceber que, quanto mais alto o nível da linguagem mais fácil é o aprendizado de programação, pois a escrita e a leitura do código são mais intuitivas e parecidas com a linguagem humana. Além disso, uma linguagem de alto nível é mais genérica, podendo ser traduzida para a linguagem de máquina de diversos tipos de microprocessadores. Já a linguagem de máquina (de baixo nível) é específica de uma determinada família de microprocessadores.
BIBLIOGRAFIA MACHADO, F. B.; MAIA F. P. “Arquitetura de Sistemas Operacionais”. 5. ed. Rio de Janeiro: LTC, 2013. TANENBAUM, A. S. “Organização estruturada de computadores”. 5. ed. São Paulo: Pearson: Prentice Hall, 2007. WEBER, R. F. “Fundamentos de Arquitetura de Computadores”. 4. ed. Porto Alegre: Bookman, 2012.
ORGANIZAÇÃO DE SISTEMAS COMPUTACIONAIS (PARTE 1) Processadores: organização da CPU, execução de instrução, princípios de projetos para computadores modernos, paralelismo no nível de instrução, paralelismo no nível de processador.
Processadores Também conhecido como UCP (Unidade Central de Processamento) ou CPU (Central Process Unit) na sigla em inglês, processador é o cérebro do computador. Sua função é executar os programas armazenados na memória principal, buscando cada uma das instruções, examinando-as e executando-as uma após a outra. É constituído de diversas partes: a unidade de controle é responsável por buscar as instruções na memória principal e por determinar o tipo de cada instrução, isto é, decodificar as instruções. A Unidade de Lógica Aritmética (ULA) realiza um conjunto de operações necessárias à execução das instruções. O processador possui uma pequena memória de alta velocidade, composta pelos registradores da CPU, utilizada para armazenar resultados temporários e informações de controle. Essa memória é formada por um conjunto de registradores, cada qual com determinado tamanho e função. O registrador mais importante é o Program Counter (PC), cujo valor aponta para a próxima instrução a ser buscada na memória para ser executada. Outros registradores importantes são o Registrador de Instruções (IR – Instruction Register) que armazena a instrução que está sendo executada, o Registrador de Status, que 21
Unidade I
armazena os bits (flags) referentes ao resultado da última operação executada (se o resultado foi zero ou negativo, por exemplo) e o Acumulador, utilizado pelos programas para armazenar os resultados das operações processadas. Processador (CPU) Registradores
Unidade Lógica Aritmética (ULA)
Sistema de interconexão da CPU
Unidade de controle
Figura 2- Estrutura de um Processador
Quando se diz que um processador é de 8, 16, 32 ou 64 bits, por exemplo, geralmente, é uma referência ao número de bits armazenados nos registradores da CPU. Uma CPU de 64 bits, por exemplo, possui um registrador acumulador de 64 bits, conectado a um barramento também de 64 bits, sendo capaz de manipular dados com esse número de bits durante uma única operação. Para ser executada pelo processador, uma instrução precisa ser dividida em uma série de passos, denominada ciclo da busca-decodificação-execução, a saber: — busca da próxima instrução na memória e armazenamento no registrador de instruções. Programas de computador são constituídos por uma sequência de instruções que se encontram armazenados na memória do computador. Portanto, o processador deve ser capaz de mover (buscar) instrução por instrução antes de executá-las. Cada instrução buscada é armazenada no registrador de instruções (Instruction Register – IR) para ser decodificada, isto é, para o processador gerar os sinais de controle que implementam a execução da operação da forma correta. — atualização do valor do program counter, de modo a apontar para a instrução seguinte. Para ser capaz de buscar instruções, o processador deve ser capaz de conhecer a localização das instruções, ou seja, endereço de cada instrução na memória. O endereço da próxima instrução a ser buscada é armazenado em um registrador especial chamado PC (Program Counter ou Contador de Programa). Esse registrador é, na realidade, um ponteiro, pois contém o endereço da próxima instrução a ser buscada na memória. 22
ARQUITETURA DE COMPUTADORES
— determinação do tipo de instrução que está armazenada no registrador de instruções. Conforme vimos, as instruções devem estar armazenadas no registrador de instruções (IR), para serem decodificadas. Na verdade, cada instrução é composta por dois campos de bits: o Opcode (ou código da operação) e o campo dos operandos. O primeiro contém o código binário que representa qual operação a instrução executa (por exemplo, uma operação aritmética, lógica, de controle ou movimento de dados). O segundo representa a informação de entrada que será tratada. Portanto, o Opcode é decodificado por um decodificador da Unidade de Controle do processador para que a instrução correta seja executada. — se a instrução precisar de uma palavra armazenada na memória, nesse passo deve ser determinado onde essa palavra está armazenada. O operando pode representar tanto o dado a ser tratado (número ou caractere no formato binário), quanto um endereço de memória onde o dado a ser tratado se encontra. No segundo caso, faz-se necessária uma segunda busca à memória. A diferença sobre a natureza do operando encontra-se codificada no opcode da instrução. — busca da palavra, se necessário, e armazenamento em um dos registradores. Se o operando é um endereço, o dado é buscado para ser armazenado em um registrador da CPU. — execução da instrução. Com todos os dados armazenados em registradores da CPU e o opcode da instrução já decodificado, a instrução está no ponto de ser executada, pois todas as informações necessárias tornam-se disponíveis ou já foram interpretadas pelo processador. Desse modo, a Unidade de Controle da CPU já pode coordenar os circuitos digitais da Unidade Lógica e Aritmética (ULA) para os dados serem processados pelos circuitos selecionados e os resultados serem obtidos. — armazenamento do resultado, Os resultados obtidos são os dados de saída da instrução executada. Resultados de operações aritméticas e lógicas tendem a ser armazenados em registradores da CPU (geralmente no registrador acumulador). Deseja-se que tais dados resultantes sejam armazenados na memória principal, faz-se necessária a execução de outra instrução para movimentar o dado de um registrador da CPU para a memória. — retorno ao primeiro passo para iniciar a execução da próxima instrução. 23
Unidade I
Durante a execução, o PC é incrementado (isto é, seu valor aumenta), de tal modo que ele aponta para a próxima instrução do programa. Geralmente, a próxima instrução localiza-se no endereço seguinte ao da instrução anterior. Entretanto, no caso de instruções de desvio, como saltos (JUMPs, GOTOs) condicionais e incondicionais chamadas a sub-rotinas (CALL) ou retorno de sub-rotina (RETURN), o endereço da instrução seguinte não é o seguinte ao da última instrução executada. Essas instruções alteram o valor do registrador PC, de modo que os programas não precisam seguir uma sequência rígida de processamento, mas podem realizar decisões condicionadas aos dados de entrada.
Princípios de Projeto para Computadores Modernos Projetistas de máquinas precisam estar sempre atentos às mudanças de tecnologia que afetam as velocidades dos componentes de um computador. Dessa forma, um conjunto de princípios de projeto deve ser observado por esses projetistas. Esses princípios são: — todas as instruções são diretamente executadas por hardware – nenhuma delas é interpretada por microinstruções. Até algum tempo, a tecnologia dominante era caracterizada por uma arquitetura de muitas instruções que realizavam operações complexas. Para tanto, utilizavam o conceito de microprogramação. Cada instrução complexa era associada a um microprograma composto por microinstruções simples. A tendência atual segue a direção oposta, isto é, processadores compostos por um número reduzido de instruções elementares, que são decodificadas e executadas diretamente pelo hardware (nível lógico digital). Assim, os programas tendem a ser compostos por um número maior de instruções mais elementares do que um número menor de instruções mais complexas. Entretanto, instruções elementares são executadas individualmente em um tempo bem menor, principalmente ao se usar técnicas de paralelismo, tais como pipelining . — maximizar a taxa à qual as instruções são executadas – o paralelismo pode representar um papel muito importante na melhora do desempenho. Uma vantagem associada a instruções mais elementares é um formato mais parecido, com um tempo de execução mais parecido e estágios mais parecidos. Essa característica propicia o uso da tecnologia conhecida como pipelining . — as instruções precisam ser facilmente decodificadas – o processo de decodificação é que determina os recursos usados na execução das instruções. Instruções mais simples (elementares) e em menor número levam a um processo de decodificação mais simples — somente as instruções de load e store devem referenciar a memória – estabelecer que os operandos para a maioria das instruções venham de e retornem para registradores. 24
ARQUITETURA DE COMPUTADORES
Os registradores da CPU ocupam o topo da hierarquia como a memória mais rápida presente em qualquer sistema computacional. Naturalmente, o desempenho é maior se os dados a serem processados estiverem nos registradores na maior parte do tempo. — projetar uma máquina com muitos registradores – como o acesso à memória é relativamente lento, há necessidade de se ter vários registradores à disposição. Os princípios descritos acima estão associados à tecnologia RISC (computadores com um conjunto reduzido de instruções), que são um contraponto à tecnologia CISC (computadores com um conjunto complexo de instruções). Uma das maneiras de melhorar o desempenho das máquinas é aumentar a velocidade do clock , porém existem limites tecnológicos para isso. Dessa forma, os projetistas focam no paralelismo como forma de obter melhor desempenho para uma mesma velocidade de clock . No nível de instruções, o paralelismo é explorado dentro das instruções individuais, de modo a conseguir que a máquina execute mais instruções por segundo. No nível de processador, vários processadores trabalham junto na solução do mesmo problema. Além disso, de nada adiantaria simplesmente aumentar a frequência do clock se há problemas com o superaquecimento, ou existir um tempo mínimo que um sinal elétrico leva para ser propagar. Aumentando a capacidade de integração, conforme a evolução da microeletrônica, permite diminuir as dimensões dos componentes e o tempo de propagação dos sinais, mas existe um limite para isso. Transistores não podem ter dimensões menores do que as de um átomo. Portanto, um bom projeto em nível de arquitetura e organização é fundamental na melhora da performance do sistema.
Paralelismo Uma forma de melhorar o desempenho é por meio de tecnologias de paralelismo, o que significa um sistema com diversos componentes trabalhando simultaneamente. Por exemplo, se um processo qualquer for constituído de duas etapas, o efeito de elas serem executadas simultaneamente é praticamente o mesmo de essas duas etapas serem executadas sequencialmente com o dobro da velocidade. Existem essencialmente dois tipos de paralelismo em sistemas computacionais, paralelismo em nível de instrução e em nível de processador:
Paralelismo no Nível de Instrução: Nesse caso temos um único processador (CPU) e o paralelismo é explorado em cada instrução individualmente. Uma instrução é, geralmente, composta por diversos estágios, que utilizam circuitos independentes, podendo, portanto, funcionar simultaneamente. Dois exemplos de tecnologias que fazem uso do paralelismo em nível de instrução são a técnica de pipelining e de processadores superescalares. 25
Unidade I
Usando a tecnologia pipeline , a arquitetura do processador tira proveito do fato de a maioria das instruções serem compostas por diversos estágios comuns. Por exemplo, toda instrução precisa ser buscada na memória (onde se encontra o programa que a contém); depois será decodificada (nesse estágio, o processador lê o código da instrução para definir qual operação será executada); algumas instruções requerem a busca de um operando na memória (dado de entrada da operação) e, por fim, a execução da operação e a gravação do resultado. Esses estágios são, muitas vezes, denominados em inglês como: Instruction Fetch (IF) – busca da instrução. Instruction Decode (ID) – decodificação do opcode da instrução. Operand Fetch (OF) – busca do operando (na memória ou em um registrador). Execution (E) – execução da operação. Write Back (WB) – gravação do resultado.
Vamos, primeiramente, observar na figura abaixo como é o processamento de um programa composto por instruções com esses 5 estágios em um processador que não faz uso da tecnologia pipeline . Sem Pipeline Instr. 1
Busca instrução
Instr. 2
Decodifica
Busca operando
Executa a operação
Armazena resultado Busca instrução
Decodifica
Busca operando
Instruções ciclos de clock
tempo
Agora, repare como é o processamento fazendo uso de uma pipeline de instruções. A busca da segunda instrução ocorreu logo após a busca da primeira instrução terminar. Enquanto a instrução 1 é decodificada, a instrução 2 é buscada. Temos sempre uma nova instrução sendo buscada a cada ciclo máquina (ou seja, ao fim de cada estágio). Efetivamente, a taxa de emissão de novas instruções foi multiplicada por 5, que é o número de estágios de cada instrução. Podemos também perceber que, após o 5º ciclo de máquina, temos 5 estágios sendo processados simultaneamente, cada um proveniente de uma instrução diferente. A velocidade do processamento é (quase) multiplicada por 5.
26
ARQUITETURA DE COMPUTADORES
Pipeline de instruções Instr. 1
Busca instrução
Instr. 2
Decodifica
Busca operando
Busca instrução
Decodifica
Executa a operação Busca operando
Busca instrução
Decodifica
Armazena resultado Executa a operação Busca operando
Busca instrução
Decodifica
Armazena resultado Executa a operação Busca operando
Busca instrução
Decodifica
Armazena resultado Executa a operação Busca operando
Busca instrução
Decodifica
Armazena resultado Executa a operação Busca operando
Busca instrução
Decodifica
Instr. 3 Instr. 4 Instruções
Instr. 5 Instr. 6 Instr. 7 ciclos de clock
tempo
Naturalmente, o tempo de cada instrução individualmente permanece o mesmo, utilizando ou não uma pipeline de instruções. Só que a taxa de emissão de instruções aumentou e temos um processamento paralelo de estágios diferentes de instruções diferentes, o que leva a um aproveitamento maior do tempo (que em um sistema computacional digital é determinado pelos ciclos de clock). A filosofia pipeline é a mesma de uma linha de montagem industrial, onde o processo de fabricação de um produto é dividido em diversos estágios ou etapas. Essas etapas são realizadas todas simultaneamente durante o processo, embora um produto possa estar no início da linha de montagem (passando pelos primeiros estágios), ou no final dela (passando pelos últimos estágios). ULA
Processador superescalar
S1 Unidade de busca de instrução
S2 Unidade de decodificação de instrução
S3 Unidade de busca do operando
ULA LOAD
S5 Unidade de gravação de cálculo
STORE Ponto flutuante Unidades de execução
Paralelismo no nível do processador: nesse caso, temos mais de uma CPU, ou núcleo (core). 27
Unidade I
BIBLIOGRAFIA NULL, L.; LOBUR J. “Princípios Básicos de Arquitetura e Organização de Computadores”. 2. ed. Porto Alegre, Bookman, 2010. TANENBAUM, A. S. “Organização estruturada de computadores”. 5. ed. São Paulo: Pearson: Prentice Hall, 2007. WEBER, R. F. “Fundamentos de Arquitetura de Computadores”. 4. ed. Porto Alegre: Bookman, 2012.
ORGANIZAÇÃO DE SISTEMAS COMPUTACIONAIS (PARTE 2) Memória primária: endereços, ordenação dos bytes, códigos de correção de erros. Memória secundária.
Organização da Memória Primária A memória é a parte do computador na qual os programas e os dados são armazenados. A memória é formada por um conjunto de células que podem guardar informações. Cada célula tem um número associado a ela, conhecido como endereço da célula, por meio do qual os programas podem referenciar a célula. Para acessar um dado (seja para leitura ou escrita), o endereço deve ser enviado do processador para a memória. Através do endereço, o dado é localizado e selecionado para uma transferência. Só é possível ler um dado, ou escrever um dado na memória, se o seu endereço houver sido informado antes, porque é o endereço que seleciona uma única célula na memória. A célula é a menor unidade endereçável de um computador. Nos últimos anos, quase todos os fabricantes de computadores padronizaram o tamanho da célula em 8 bits , chamando essa célula de byte . Os bytes são agrupados em palavras. O computador com palavra de 32 bits tem 4 bytes /palavra, enquanto um computador com palavra de 64 bits tem 8 bytes /palavra. A maioria das instruções de uma máquina opera sobre a palavra que a CPU pode processar. Quando dizemos que um processador é de 64 ou 32 bits , estamos dizendo que esse é o tamanho da palavra do processador. Geralmente, a palavra do processador é igual ao número de bits dos seus registradores e ao número de vias dos seus barramentos internos. Palavras compostas por mais de um byte são denominadas da seguinte forma: Byte: 8 bits Word: 16 bits ou 2 bytes. Dword: (double word) 32 bits ou 4 bytes. Qword: (quad word) 64 bits ou 8 bytes. 28
ARQUITETURA DE COMPUTADORES
Temos 3 tipos de sinais nas vias de barramentos que conectam o processador à memória:
— vias de dados — vias de endereço — vias de controle As vias de dados movimentam os dados que importam. Os dados que são provenientes da memória (em caso de uma operação de leitura), ou que são provenientes do processador para a memória (em caso de operação de escrita). As vias de endereço enviam sinais digitais do processador para a memória, já que é o processador que seleciona o endereço a ser acessado. Durante a execução de uma instrução de um programa, o endereço pode, por exemplo, estar contido no código da instrução, ou ser calculado durante a execução do programa. As vias de controle enviam sinais do processador para a memória ou vice-versa. Definem, por exemplo, se o processo a ser executado será uma leitura ou uma escrita na memória. Também podem informar se a memória (ou outro dispositivo) está pronta ou não para iniciar uma comunicação com o processador.
Ordenação de Bytes Os bytes de uma palavra podem ser numerados da esquerda para a direita ou da direita para a esquerda. A escolha acarreta implicações muito sérias e importantes. Melhor dizendo, a memória de um computador pode estar organizada de tal maneira que cada palavra pode ser armazenada com o byte mais significativo no endereço mais alto ou no endereço mais baixo. O primeiro caso é denominado little endian e o segundo, big endian. A figura 1 mostra parte de uma memória de um computador de 32 bits cujos bytes são numerados da esquerda para a direita. A fig. 2 mostra a representação da memória de um computador de 32 bits cujos bytes de uma palavra são numerados da direita para a esquerda. O computador da fig. 1 é chamado big endian, enquanto que o computador da fig. 2 é denominado little endian. Endereço 0 4 8 12
0 4 8 12
Big endian 1 2 5 6 9 10 13 14 ß Palavra de 32 bits à Fig. 1
3 7 11 15 Byte
3 7 11 15
Little endian 2 1 6 5 10 9 14 13
0 4 8 12
Endereço 0 4 8 12 Byte
ß Palavra de 32 bits à Fig. 2 29
Unidade I
Códigos de Correção de Erros Os dados armazenados na memória dos computadores podem ocasionalmente ser alterados em razão de oscilações na tensão de alimentação ou outras causas. Para se prevenir contra esses tipos de erro, algumas memórias armazenam informações usando um código que permita a correção ou a detecção de erros. Quando esses códigos são usados, é necessário acrescentar bits extras a cada palavra de memória, de modo a permitir a verificação da exatidão da palavra armazenada. Quando uma palavra é lida da memória, os bits armazenados permitem verificar a ocorrência eventual de erros que tenham corrompido a informação armazenada. Acrescentar bits extras à informação é aumentar a redundância da informação. A informação redundante deve ser uma função da informação útil, de tal maneira que em caso de algum bit ser corrompido, a relação funcional deixa de existir e um erro é detectado. Uma forma de se detectar erros é por meio de um bit de paridade adicional. Essa técnica consiste em inserir um bit com valor tal que o número de bits com valor 1 na sequência seja sempre par (ou ímpar). Dessa forma, a mudança de um bit provocada por erro de transmissão leva a uma alteração na paridade: O número de 1s na sequência passa a ser ímpar quando deveria ser par, por exemplo. Essa forma de detecção de erros foi muito utilizada na transmissão serial via protocolo RS-232, utilizado em impressoras antes da tecnologia USB. Por outro lado, uma forma de se detectar e corrigir o erro provocado pela inversão de um bit é o Código de Hamming. No código de Hamming, para 4 bits de informação útil, por exemplo, outros 3 bits de redundância são inseridos na sequência. O algoritmo de correção de Hamming pode ser melhor compreendido por meio de uma representação por conjuntos. Os 4 bits centrais da figura abaixo constituem a informação útil. Os 3 bits externos correspondem aos bits de redundância, cujo valor é determinado de tal maneira que o número de bits de valor 1 em cada círculo seja sempre par. Por exemplo, se temos os seguintes 4 bits com informação útil:
30
ARQUITETURA DE COMPUTADORES
1 1 1
0
Então, os 3 bits do código de correção de erro devem ser preenchidos da seguinte maneira:
1
1
0
1 1
0
0
Exemplo: No código de Hamming descrito abaixo, descubra qual é o bit com erro e o corrija:
1
1
0
0 1
1
0
Resolução: Podemos perceber na figura acima que o único círculo com número ímpar de bits de valor 1 é o da esquerda. Portanto, o bit com erro é exclusivo desse círculo. Abaixo, esse bit é corrigido.
31
Unidade I
0
1
0
0 1
1
0
Outro exemplo: corrija o bit com erro no código de Hamming a seguir:
0
0
0
1 1
1
1
Resolução: O círculo superior esquerdo possui paridade par, portanto, nenhum bit pertencente a ele possui erro. Os outros dois círculos possuem paridade ímpar, portanto, o erro está em um bit na intersecção desses dois círculos, mas que não pertence ao círculo da esquerda, cuja paridade está correta.
0
0
0
1 1
1
1
32