Módulo 0: Nivelamento de Conhecimentos Prévios

Este módulo especial foi elaborado para revisar e consolidar conhecimentos fundamentais que você precisará dominar ao longo da disciplina de Arquitetura e Organização de Computadores. O conteúdo aqui apresentado não é novo, mas representa conceitos que serão utilizados constantemente durante todo o semestre. Dedique atenção especial a esta revisão, pois lacunas nestes fundamentos podem comprometer seriamente sua compreensão dos tópicos mais avançados.

Apresentação e Objetivos

Antes de embarcarmos na jornada fascinante pelo interior dos computadores, precisamos garantir que você possua uma base sólida em conceitos fundamentais. Este módulo de nivelamento foi cuidadosamente elaborado após análise das respostas na avaliação diagnóstica, revelando áreas específicas que merecem revisão aprofundada. Não se preocupe se alguns destes tópicos parecerem familiares enquanto outros apresentam desafios, pois a proposta aqui é justamente estabelecer um ponto de partida comum para toda a turma.

A compreensão profunda de arquitetura de computadores exige que você seja capaz de transitar fluidamente entre diferentes níveis de abstração. Você precisará entender como números são representados em sistemas binários, como circuitos lógicos processam informações, como componentes armazenam estados e como todos estes elementos se conectam para formar sistemas computacionais funcionais. Este módulo preparatório estabelecerá os alicerces sobre os quais todo o conhecimento subsequente será construído.

O diagrama a seguir ilustra como os tópicos deste módulo de nivelamento se relacionam entre si e com o conteúdo que você estudará nos módulos regulares da disciplina.

flowchart TD
    subgraph NIVEL["Módulo de Nivelamento"]
        A[Sistemas de Numeração] --> B[Aritmética Binária]
        B --> C[Complemento de Dois]
        D[Portas Lógicas Básicas] --> E[XOR e Comparadores]
        E --> F[Componentes MSI]
        F --> G[MUX e Decodificadores]
        H[Lógica Combinacional] --> I[Lógica Sequencial]
        I --> J[Flip-Flops e Registradores]
        J --> K[Sincronização por Clock]
    end
    
    subgraph MOD1["Módulo 1"]
        L[Arquitetura Von Neumann]
    end
    
    subgraph MOD2["Módulo 2"]
        M[Representação de Dados]
        N[IEEE 754]
    end
    
    subgraph MOD3["Módulo 3"]
        O[Caminho de Dados]
        P[ULA e Registradores]
    end
    
    C --> M
    C --> P
    G --> O
    K --> L
    K --> O
    
    style NIVEL fill:#f5f5f5,stroke:#333
    style MOD1 fill:#e3f2fd,stroke:#1976d2
    style MOD2 fill:#e3f2fd,stroke:#1976d2
    style MOD3 fill:#e3f2fd,stroke:#1976d2

Sistemas de Numeração: Fundamentos para Arquitetura

Por que Binário e Hexadecimal Importam

Você já aprendeu sobre sistemas de numeração em disciplinas anteriores, mas agora precisa compreendê-los sob uma perspectiva diferente. Os computadores não escolhem trabalhar com números binários por capricho dos engenheiros, mas porque esta é a forma mais confiável de representar informação usando circuitos eletrônicos. Um transistor pode estar conduzindo corrente ou não, uma tensão pode estar em nível alto ou baixo, um capacitor pode estar carregado ou descarregado. Estas duas condições físicas distintas mapeiam naturalmente para os dígitos zero e um do sistema binário.

O sistema hexadecimal, por sua vez, não é utilizado porque os computadores pensam em hexadecimal, mas porque nós, humanos, precisamos de uma forma compacta de visualizar valores binários. Um número binário de 32 bits seria escrito como uma sequência de 32 zeros e uns, algo difícil de ler e propenso a erros. O mesmo número em hexadecimal requer apenas 8 dígitos, uma representação muito mais gerenciável.

A relação entre hexadecimal e binário é particularmente elegante. Cada dígito hexadecimal corresponde exatamente a quatro dígitos binários, o que torna a conversão entre estes sistemas trivial. Quando você observa um endereço de memória como 0x1A3F, pode imediatamente expandir cada dígito hexadecimal em seu equivalente de quatro bits: 1 torna-se 0001, A torna-se 1010, 3 torna-se 0011 e F torna-se 1111, resultando em 0001101000111111 em binário. Esta conversão direta é impossível com o sistema decimal, que não possui esta relação de potência de dois com o binário.

Tabela de Correspondência: Decimal, Binário e Hexadecimal

Decimal Binário Hexadecimal
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F

Esta tabela deve ser memorizada, pois você a utilizará constantemente ao longo da disciplina e em sua carreira profissional. Observe como cada dígito hexadecimal representa exatamente um grupo de quatro bits, também chamado de nibble.

Conversão entre Sistemas: Método Sistemático

Para converter um número decimal para binário, você divide sucessivamente por dois, anotando os restos. Os restos, lidos de baixo para cima, formam o número binário. Vamos converter o número decimal 45 para binário como exemplo detalhado.

Iniciamos dividindo 45 por 2, obtendo quociente 22 e resto 1. Dividimos 22 por 2, obtendo quociente 11 e resto 0. Dividimos 11 por 2, obtendo quociente 5 e resto 1. Dividimos 5 por 2, obtendo quociente 2 e resto 1. Dividimos 2 por 2, obtendo quociente 1 e resto 0. Finalmente, dividimos 1 por 2, obtendo quociente 0 e resto 1. Lendo os restos de baixo para cima, obtemos 101101, que é a representação binária de 45.

Para verificar, podemos converter de volta para decimal calculando 1 \times 2^5 + 0 \times 2^4 + 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 32 + 0 + 8 + 4 + 0 + 1 = 45.

A conversão de binário para hexadecimal é mais direta. Agrupamos os bits em conjuntos de quatro, da direita para a esquerda, completando com zeros à esquerda se necessário, e substituímos cada grupo pelo dígito hexadecimal correspondente. Para converter 101101 para hexadecimal, primeiro completamos para oito bits: 00101101. Separamos em dois grupos de quatro: 0010 e 1101. O grupo 0010 corresponde ao dígito 2, e o grupo 1101 corresponde ao dígito D. Portanto, 45 em decimal equivale a 0x2D em hexadecimal.

Representação de Números Negativos: O Complemento de Dois

Por que o Complemento de Dois é Essencial

A representação de números negativos em computadores é um dos conceitos mais importantes que você precisa dominar antes de prosseguir com a disciplina. Enquanto nós, humanos, simplesmente colocamos um sinal de menos na frente de um número para indicar que ele é negativo, os computadores precisam de uma forma de representar este sinal usando apenas zeros e uns.

A abordagem mais intuitiva seria utilizar um bit para representar o sinal, com zero indicando positivo e um indicando negativo. Esta representação, chamada de sinal e magnitude, funciona bem para humanos mas apresenta problemas sérios para hardware. Primeiro, existiriam duas representações para o zero: 00000000 para +0 e 10000000 para -0. Segundo, a soma de números positivos e negativos exigiria circuitos separados para verificar os sinais e decidir se deve somar ou subtrair as magnitudes.

O complemento de dois resolve elegantemente estes problemas. Nesta representação, existe apenas uma representação para o zero, e a mesma circuitaria que realiza soma de números positivos funciona automaticamente para números negativos. Esta economia de hardware foi decisiva para que o complemento de dois se tornasse o padrão universal em computadores.

Como Funciona o Complemento de Dois

Em um sistema de complemento de dois com n bits, os números positivos são representados normalmente em binário, desde zero até 2^{n-1} - 1. Por exemplo, com 8 bits, os números positivos vão de 0 (00000000) até 127 (01111111). Observe que todos os números positivos têm o bit mais significativo igual a zero.

Os números negativos são representados de forma que a soma de um número com seu negativo resulte em zero. Para encontrar a representação de um número negativo, você inverte todos os bits do número positivo correspondente e soma um. Este processo é chamado de complementação.

Vamos encontrar a representação de -45 em complemento de dois com 8 bits. Primeiro, escrevemos 45 em binário: 00101101. Em seguida, invertemos todos os bits, obtendo 11010010. Finalmente, somamos um: 11010010 + 1 = 11010011. Portanto, -45 em complemento de dois com 8 bits é 11010011.

Para verificar, somamos 45 e -45 usando aritmética binária comum:

  00101101  (+45)
+ 11010011  (-45)
-----------
 100000000

O resultado tem 9 bits, mas como estamos trabalhando com 8 bits, o bit extra é descartado, resultando em 00000000, que é exatamente zero. Esta é a beleza do complemento de dois: a soma funciona automaticamente, sem necessidade de tratamento especial para sinais.

Intervalo de Representação em Complemento de Dois

Com n bits em complemento de dois, podemos representar números de -2^{n-1} até 2^{n-1} - 1.

Bits Mínimo Máximo Total de Valores
4 -8 +7 16
8 -128 +127 256
16 -32768 +32767 65536
32 -2147483648 +2147483647 4294967296

Observe que o intervalo não é simétrico: existe um número negativo a mais do que números positivos. Este número adicional, que não possui equivalente positivo, é chamado de “número mágico” ou “número estranho” do complemento de dois.

Identificando Números Negativos

Em complemento de dois, o bit mais significativo indica o sinal do número: zero para positivo e um para negativo. Entretanto, diferentemente da representação de sinal e magnitude, este bit também contribui para o valor numérico. Quando o bit mais significativo é um, você não pode simplesmente ignorá-lo e interpretar o restante como magnitude.

Para converter um número negativo em complemento de dois de volta para decimal, existem duas abordagens. A primeira é aplicar o mesmo processo de complementação novamente, que sempre retorna ao valor original positivo. A segunda é atribuir peso negativo ao bit mais significativo na expansão posicional.

Por exemplo, para interpretar 11010011 (que sabemos ser -45), podemos calcular: -1 \times 2^7 + 1 \times 2^6 + 0 \times 2^5 + 1 \times 2^4 + 0 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0. Isto resulta em -128 + 64 + 16 + 2 + 1 = -45.

Subtração Usando Complemento de Dois

Uma das maiores vantagens do complemento de dois é que a subtração pode ser realizada como uma soma. Para calcular A - B, basta calcular A + (-B), onde -B é obtido pela complementação de B. O hardware de soma funciona para ambas as operações, economizando circuitaria significativa.

Vamos calcular 57 - 45 usando complemento de dois com 8 bits. Primeiro, representamos 57 em binário: 00111001. Já sabemos que -45 em complemento de dois é 11010011. Agora somamos:

  00111001  (+57)
+ 11010011  (-45)
-----------
 100001100

Descartando o bit de estouro, obtemos 00001100, que em decimal é 12. De fato, 57 - 45 = 12.

Portas Lógicas: Os Blocos Fundamentais

Revisão das Portas Básicas

As portas lógicas são os componentes mais elementares dos circuitos digitais. Toda a complexidade de um processador moderno, com bilhões de transistores, é construída a partir de combinações destas portas simples. Você já estudou portas lógicas anteriormente, mas vamos revisá-las com foco em suas aplicações em arquitetura de computadores.

A porta AND produz saída um apenas quando todas as suas entradas são um. Esta porta é frequentemente utilizada para habilitar ou desabilitar sinais. Por exemplo, um sinal de dado pode ser “mascarado” fazendo AND com um sinal de controle: quando o controle é zero, a saída é sempre zero, independentemente do dado; quando o controle é um, a saída reproduz o dado.

A porta OR produz saída um quando pelo menos uma de suas entradas é um. Esta porta é útil para combinar múltiplas condições onde qualquer uma delas é suficiente para ativar uma ação.

A porta NOT, também chamada de inversor, simplesmente inverte seu único bit de entrada. Zeros tornam-se uns e uns tornam-se zeros. Esta porta, embora simples, é essencial para criar complementos e inverter condições lógicas.

Tabelas Verdade das Portas Básicas

A B AND OR NAND NOR
0 0 0 0 1 1
0 1 0 1 1 0
1 0 0 1 1 0
1 1 1 1 0 0
A NOT
0 1
1 0

As portas NAND e NOR são versões negadas de AND e OR, respectivamente. Qualquer função lógica pode ser implementada usando apenas portas NAND, ou usando apenas portas NOR, o que as torna especialmente importantes na fabricação de circuitos integrados.

A Porta XOR e Suas Aplicações

A porta XOR, ou exclusive OR, merece atenção especial por sua importância em arquitetura de computadores. Esta porta produz saída um quando suas entradas são diferentes, e saída zero quando são iguais. A tabela verdade da porta XOR é apresentada a seguir.

A B XOR
0 0 0
0 1 1
1 0 1
1 1 0

Você pode pensar na porta XOR como respondendo à pergunta “as entradas são diferentes?”. Quando A e B são diferentes, a saída é um (verdadeiro); quando são iguais, a saída é zero (falso).

A porta XOR possui aplicações fundamentais em computação. Na aritmética binária, o XOR é utilizado para calcular o bit de soma em somadores, pois a soma de dois bits (ignorando o vai-um) segue exatamente a tabela do XOR. Na criptografia, XOR é a base de muitos algoritmos de cifragem, pois aplicar XOR duas vezes com a mesma chave recupera o valor original. Na detecção de erros, XOR é usado para calcular bits de paridade.

A Porta XNOR como Comparador

A porta XNOR é simplesmente a negação do XOR. Onde o XOR produz um, o XNOR produz zero, e vice-versa. A tabela verdade do XNOR é:

A B XNOR
0 0 1
0 1 0
1 0 0
1 1 1

Observe que o XNOR produz saída um exatamente quando as entradas são iguais. Isto torna o XNOR perfeito para comparar bits: se você quer verificar se dois bits A e B são iguais, basta aplicar XNOR e observar a saída.

Para comparar dois números de múltiplos bits, você pode aplicar XNOR bit a bit e então usar uma porta AND para combinar todos os resultados. Se todos os bits correspondentes forem iguais, todas as saídas XNOR serão um, e o AND de todos produzirá um, indicando igualdade. Se qualquer par de bits for diferente, o XNOR correspondente produzirá zero, e o AND de todos produzirá zero, indicando desigualdade.

flowchart LR
    subgraph Comparador de 4 bits
        A0[A0] --> X0[XNOR]
        B0[B0] --> X0
        A1[A1] --> X1[XNOR]
        B1[B1] --> X1
        A2[A2] --> X2[XNOR]
        B2[B2] --> X2
        A3[A3] --> X3[XNOR]
        B3[B3] --> X3
        X0 --> AND[AND]
        X1 --> AND
        X2 --> AND
        X3 --> AND
        AND --> EQ[A = B]
    end

Componentes MSI: Multiplexadores e Decodificadores

O que são Componentes MSI

Os componentes MSI, ou Medium Scale Integration, representam circuitos que combinam múltiplas portas lógicas para realizar funções mais complexas. Antes da era da integração em larga escala, estes componentes eram vendidos como chips individuais, e projetistas os combinavam para construir sistemas digitais. Embora hoje os processadores integrem bilhões de transistores em um único chip, os mesmos princípios funcionais dos componentes MSI estão presentes internamente.

Dois componentes MSI são particularmente importantes para compreender a arquitetura de computadores: o multiplexador e o decodificador. Estes componentes aparecem repetidamente no caminho de dados e na unidade de controle de processadores, e você precisa compreendê-los profundamente antes de estudar estes tópicos.

Multiplexador: O Seletor de Dados

O multiplexador, frequentemente abreviado como MUX, é um seletor que escolhe uma entre várias entradas de dados e a direciona para a saída. Você pode pensar no multiplexador como uma chave seletora que pode ser posicionada em diferentes posições, cada posição conectando uma entrada diferente à saída.

Um multiplexador de duas entradas possui uma entrada de seleção S, duas entradas de dados D0 e D1, e uma saída Y. Quando S é zero, a saída Y recebe o valor de D0. Quando S é um, a saída Y recebe o valor de D1. A tabela verdade completa é:

S D0 D1 Y
0 0 X 0
0 1 X 1
1 X 0 0
1 X 1 1

O X na tabela indica “don’t care”, significando que o valor daquela entrada não afeta a saída naquela condição.

A expressão booleana para este multiplexador é: Y = \overline{S} \cdot D0 + S \cdot D1

Quando S é zero, o termo \overline{S} é um, habilitando D0, enquanto S é zero, desabilitando D1. Quando S é um, ocorre o inverso.

flowchart TD
    subgraph MUX["Multiplexador 2:1"]
        D0[D0] --> M[MUX]
        D1[D1] --> M
        S[S] --> M
        M --> Y[Y]
    end

Multiplexadores maiores seguem o mesmo princípio. Um MUX 4:1 tem quatro entradas de dados, duas linhas de seleção (para codificar quatro possibilidades), e uma saída. Um MUX 8:1 tem oito entradas de dados, três linhas de seleção, e assim por diante. Em geral, um MUX com n linhas de seleção pode escolher entre 2^n entradas de dados.

Aplicações de Multiplexadores em Processadores

Os multiplexadores são onipresentes no caminho de dados de processadores. Considere a seguinte situação: a ULA pode receber seu segundo operando de um registrador ou de um valor imediato embutido na instrução. Como a ULA possui apenas uma entrada para este operando, um multiplexador é usado para selecionar qual fonte de dados será utilizada. A unidade de controle gera o sinal de seleção apropriado baseado no tipo de instrução sendo executada.

Outro exemplo ocorre no acesso a memória. O endereço de memória pode vir do Program Counter (para buscar instruções) ou de um cálculo de endereço (para acessar dados). Novamente, um multiplexador seleciona qual endereço será enviado ao barramento de endereços.

Decodificador: O Ativador de Linhas

O decodificador é um componente que recebe um código de entrada de n bits e ativa exatamente uma de 2^n linhas de saída. Você pode pensar no decodificador como um tradutor que converte um número binário em uma ativação posicional.

Um decodificador 2:4 possui duas entradas A1 e A0, e quatro saídas Y0, Y1, Y2 e Y3. Dependendo do valor codificado nas entradas, exatamente uma saída é ativada:

A1 A0 Y0 Y1 Y2 Y3
0 0 1 0 0 0
0 1 0 1 0 0
1 0 0 0 1 0
1 1 0 0 0 1

Quando as entradas são 00, a saída Y0 é ativada. Quando são 01, Y1 é ativada. Quando são 10, Y2 é ativada. Quando são 11, Y3 é ativada.

flowchart TD
    subgraph DEC["Decodificador 2:4"]
        A0[A0] --> D[DEC]
        A1[A1] --> D
        D --> Y0[Y0]
        D --> Y1[Y1]
        D --> Y2[Y2]
        D --> Y3[Y3]
    end

Aplicações de Decodificadores em Processadores

Os decodificadores são fundamentais no endereçamento de memória. Quando um processador quer acessar uma posição específica da memória, ele coloca o endereço no barramento de endereços. Um decodificador dentro do chip de memória interpreta este endereço e ativa a wordline correspondente, permitindo acesso às células de memória naquele endereço.

Na seleção de registradores, decodificadores determinam qual registrador será lido ou escrito. O campo de registrador na instrução é decodificado para ativar a linha de habilitação do registrador apropriado.

Na unidade de controle, o opcode da instrução é parcialmente decodificado para determinar qual tipo de operação deve ser realizada. Diferentes opcodes ativam diferentes caminhos de controle.

Lógica Sequencial: Memória e Estado

Diferença entre Lógica Combinacional e Sequencial

Até agora revisamos circuitos combinacionais, onde a saída depende exclusivamente das entradas atuais. Portas lógicas, multiplexadores e decodificadores são todos circuitos combinacionais. Se você conhece os valores de todas as entradas, pode determinar imediatamente as saídas, sem necessidade de saber nada sobre o histórico do circuito.

Circuitos sequenciais, por outro lado, possuem memória. Suas saídas dependem não apenas das entradas atuais, mas também do estado interno do circuito, que por sua vez depende da história das entradas. Um computador precisa de circuitos sequenciais para armazenar instruções, dados e o estado de execução do programa.

Latches: Armazenamento Sensível a Nível

O latch é o elemento de memória mais simples, capaz de armazenar um único bit de informação. O latch SR (Set-Reset) básico é construído com duas portas NOR interligadas, criando uma estrutura com realimentação que pode manter seu estado indefinidamente enquanto alimentado.

O latch D (Data) é uma variação mais prática que elimina a condição proibida do latch SR. Ele possui uma entrada de dados D e uma entrada de habilitação E. Quando E é ativada, a saída Q acompanha a entrada D. Quando E é desativada, a saída Q mantém o último valor capturado.

O problema fundamental dos latches é que eles são sensíveis ao nível do sinal de habilitação. Durante todo o tempo em que E está ativo, a saída continua acompanhando a entrada. Isto pode causar problemas sérios em circuitos complexos, onde mudanças podem se propagar de forma imprevisível enquanto o sinal de habilitação está ativo.

Flip-Flops: Armazenamento Sensível a Borda

O flip-flop resolve o problema dos latches ao ser sensível apenas às bordas do sinal de clock, não ao nível. Um flip-flop D captura o valor de sua entrada D apenas no instante exato da borda de subida (ou descida, dependendo do projeto) do clock. Durante todo o restante do tempo, a saída permanece estável, independentemente de mudanças na entrada.

Esta característica é fundamental para o funcionamento de processadores. O sinal de clock define momentos discretos no tempo quando estados são capturados e atualizados. Entre bordas de clock, os sinais podem se propagar através de circuitos combinacionais, estabilizando antes da próxima borda. Na borda, todos os flip-flops capturam simultaneamente seus novos valores, atualizando o estado do sistema de forma síncrona e previsível.

sequenceDiagram
    participant CLK as Clock
    participant D as Entrada D
    participant Q as Saída Q
    
    Note over CLK,Q: Flip-flop D sensível a borda de subida
    CLK->>CLK: Borda de subida
    D->>Q: Valor capturado
    Note over Q: Q mantém valor
    D->>D: D pode mudar
    Note over Q: Q não muda
    CLK->>CLK: Próxima borda
    D->>Q: Novo valor capturado

O Papel do Clock na Sincronização

O sinal de clock é o maestro que coordena todas as operações em um processador síncrono. Este sinal oscila periodicamente entre níveis alto e baixo, e as bordas desta oscilação definem os momentos em que transições de estado ocorrem.

A frequência do clock determina quantas operações por segundo o processador pode realizar. Um clock de 1 GHz produz um bilhão de bordas por segundo, permitindo potencialmente um bilhão de atualizações de estado. Entretanto, a frequência máxima é limitada pelo tempo necessário para os sinais se propagarem através dos circuitos combinacionais entre flip-flops.

Cada ciclo de clock deve ser longo o suficiente para que os sinais se propaguem do flip-flop de origem, através de toda a lógica combinacional intermediária, até a entrada do flip-flop de destino, onde devem estabilizar antes da próxima borda. Se o período de clock for muito curto, os valores podem não ter tempo de estabilizar, causando erros de funcionamento.

Registradores: Múltiplos Flip-Flops em Paralelo

Um registrador é simplesmente um conjunto de flip-flops operando em paralelo, compartilhando o mesmo sinal de clock. Um registrador de 8 bits contém oito flip-flops D, cada um armazenando um bit de uma palavra de 8 bits. Todos capturam seus novos valores simultaneamente na borda do clock.

Os registradores são componentes fundamentais em processadores. O Program Counter é um registrador que armazena o endereço da próxima instrução a ser executada. O Instruction Register armazena a instrução atualmente em execução. O banco de registradores de propósito geral armazena dados sendo processados. O registrador de status armazena flags indicando condições como resultado zero, overflow ou carry.

Conexão Hardware-Software: Barramentos e Abstração

O Conceito de Barramento

Um barramento é um conjunto de linhas condutoras compartilhadas que transportam sinais entre componentes de um sistema computacional. Você pode pensar no barramento como uma estrada que conecta diferentes partes da cidade, permitindo que informações trafeguem de um componente a outro.

Os três tipos principais de barramentos em um sistema computacional são o barramento de dados, o barramento de endereços e o barramento de controle. O barramento de dados transporta os valores que estão sendo processados ou armazenados. O barramento de endereços transporta as localizações onde os dados devem ser escritos ou de onde devem ser lidos. O barramento de controle transporta sinais que coordenam as operações, como sinais de leitura, escrita e clock.

A largura do barramento de dados determina quantos bits podem ser transferidos simultaneamente. Um barramento de dados de 32 bits transfere 32 bits por operação. A largura do barramento de endereços determina quantas posições de memória podem ser endereçadas. Um barramento de endereços de 32 bits pode endereçar 2^{32} = 4.294.967.296 posições diferentes.

Do Programa ao Hardware

Quando você escreve um programa em linguagem de alto nível, este passa por diversas transformações antes de ser executado pelo hardware. O compilador traduz o código fonte em linguagem de montagem ou diretamente em código de máquina. O código de máquina consiste em sequências de bits que o hardware pode interpretar e executar.

Cada instrução de máquina especifica uma operação a ser realizada e os operandos envolvidos. O processador busca a instrução da memória através do barramento, decodifica-a para determinar qual operação realizar, busca os operandos necessários, executa a operação e armazena o resultado. Este ciclo se repete para cada instrução do programa.

Os ponteiros que você utiliza em linguagens como C correspondem diretamente a endereços de memória que serão colocados no barramento de endereços. Quando você desreferencia um ponteiro, o processador coloca aquele endereço no barramento e realiza uma operação de leitura ou escrita no barramento de dados.

Representação de Dados na Memória

A memória RAM armazena dados como padrões de bits. Cada posição de memória armazena uma quantidade fixa de bits, tipicamente um byte (8 bits). Números inteiros maiores ocupam múltiplas posições consecutivas. Um inteiro de 32 bits ocupa quatro bytes consecutivos na memória.

A convenção de ordenação dos bytes varia entre arquiteturas. Em sistemas little-endian, o byte menos significativo é armazenado no endereço mais baixo. Em sistemas big-endian, o byte mais significativo é armazenado primeiro. Esta diferença é importante quando dados são transferidos entre sistemas com convenções diferentes.

Números em ponto flutuante seguem o padrão IEEE 754, que define como o sinal, o expoente e a mantissa de um número são codificados em bits. Você estudará este padrão detalhadamente no Módulo 2, mas é importante saber desde já que ele existe e é universalmente utilizado.

Síntese: Preparação para a Jornada

Este módulo de nivelamento revisou conceitos fundamentais que você utilizará constantemente ao longo da disciplina. Os sistemas de numeração binário e hexadecimal são a linguagem em que os computadores pensam. O complemento de dois é a forma universal de representar números negativos em hardware digital. As portas lógicas são os blocos básicos de construção de todos os circuitos digitais. Os multiplexadores e decodificadores são componentes essenciais do caminho de dados de processadores. Os flip-flops e registradores proporcionam a memória necessária para armazenar estado. O sinal de clock sincroniza todas as operações. Os barramentos conectam os componentes permitindo comunicação.

Você está agora preparado para iniciar a jornada pelo interior dos computadores. No Módulo 1, você estudará os fundamentos de arquitetura e organização, compreendendo as diferenças entre estes conceitos e explorando as arquiteturas de Von Neumann e Harvard. Os conhecimentos revisados neste módulo de nivelamento serão aplicados e expandidos a cada passo desta jornada.

Lembre-se de que a compreensão profunda vem da prática. À medida que você avança nos módulos da disciplina, volte a este material de nivelamento sempre que necessário. Os conceitos aqui apresentados não são apenas pré-requisitos teóricos, mas ferramentas práticas que você utilizará repetidamente ao analisar e projetar sistemas computacionais.

Exercício de Autoavaliação

Antes de prosseguir para o Módulo 1, verifique se você consegue realizar as seguintes tarefas sem consultar o material:

Converta o número decimal 93 para binário e para hexadecimal.

Represente -93 em complemento de dois usando 8 bits.

Calcule 25 - 93 usando aritmética de complemento de dois com 8 bits e interprete o resultado.

Desenhe a tabela verdade de um multiplexador 2:1.

Explique a diferença entre um latch e um flip-flop.

Descreva o papel do sinal de clock em um processador síncrono.

Se você conseguiu responder todas estas questões corretamente, está pronto para prosseguir. Se teve dificuldades em alguma, releia a seção correspondente antes de avançar.