1.1. A arquitectura de uma CPU

Uma unidade de processamento central (CPU) é constituída pelas seguintes unidades funcionais interligadas:

Os registos são unidades de armazenamento temporário incluídas no CPU. Alguns registos, como é o caso do contador de programa e o registo de instruções, possuem funções específicas. Outros registos, como é o caso do acumulador, são para usos gerais.

Acumulador

O acumulador guarda normalmente um dos operandos a ser tratados pela ALU. Uma instrução típica pode ordenar à ALU para adicionar o conteúdo de um qualquer registo ao do acumulador e guardar o resultado no acumulador. Em geral, o acumulador é um registo fonte (operando) e um destino (resultado).

Normalmente uma CPU contem outros registos de uso geral que podem ser utilizados para guardar operandos ou dados intermédios. A existência de registos de uso geral, torna desnecessário transferir resultados intermédios entre a memória e o acumulador, melhorando assim a velocidade de tratamento dos dados. 

Contador de Programa

As instruções que constituem um programa são armazenadas na memória do sistema. O procesador central referencia o conteúdo da memória, de modo a determinar qual a acção apropriada. Isso significa que o processador tem que saber qual a localização de memória que contem a instrução seguinte.

Cada uma das localizações de memória é numerada, de modo a distingui-la de qualquer outra. O número que identifica a localização de memória é designada Endereço (Address).

O processador mantem um contador que contem o endereço da próxima instrução de programa. Esse registo é designado por Contador de Programa (Programa Counter). O processador actualiza o contador de programa adicionando uma unidade ao contador, cada vez que executa uma instrução, de modo que o contador de programa está sempre actualizado (apontando para a próxima instrução a executar).

O programador vai armazenar as instruções do programa em posições de memória numericamente adjacentes, de modo a que os endereços mais baixos contenham as primeiras instruções a ser executadas. O programador pode violar esta ordem sequencial utilizando uma instrução de salto (Jump) par aoutra zona de memória.

Uma instrução de salto contem o endereço da instrução a ser executada. A instrução seguinte pode ser guardada em qualquer localização de memória, já que o seu endereço é indicado na instrução de salto. Durante a execução de uma instrução de salto, o processador substitui o conteúdo do contador de programa pelo endereço especificado na instrução de salto. Desse modo se mantem a continuidade lógica do programa.

Um tipo especial de salto de programa ocorre sempre que o programa Chama uma subrotina (Call). Neste tipo de salto, o processador deverá lembrar-se do endereço contido no contador de programa na altura do salto. Isso permitirá ao processador regressar à execução do programa principal quando terminar a última instrução da subrotina.

Uma Subrotina é um programa dentro do programa. Normalmente trata-se de um conjunto de instruções que irão ser executadas repetidamente, durante a execução do programa principal. As rotinas de cálculo do quadrado, do seno ou do logaritmo de uma variável estão neste caso de funções habitualmente escritas como subrotinas. Outros exemplos podem ser os de programas destinados a enviar ou receber dados de um dispositivo periférico externo.

O processador tem um modo especial de lidar com subrotinas, de modo a assegurar um regresso ordenado ao programa principal. Quando o processador recebe uma instrução Call, incrementa o Contador de Programa e guarda o conteúdo do contador numa zona reservada de memória designada por Pilha (Stack). A Pilha guarda o endereço da instrução a ser executada a seguir à execução da subrotina. A seguir o processador carrega o endereço especificado na instrução Call no Contador de Programa. A instrução seguinte a ser executada é a primeira da subrotina.

A última instrução de uma subrotina é a instrução Return. Essa instrução não necessita de especificar endereço. Quando o processador executa uma instrução Return, carrega o contador de Programa com o endereço existente no topo da Pilha. Isto leva o processador a terminar a execução da subrotina e regressar ao programa principal para executar a instrução seguinte à instrução Call.

As subrotina dizem-se imbricadas, sempre que uma chama outra, que por sua vez chama outra, etc. Isso é aceitável desde que o processador possua memória suficiente para guardar os endereços de retorno necessários. Isto é, a profundidade máxima de criação de subrotinas imbricadas depende da dimensão da Pilha.

Os processadores possuem modos diferentes de gerir a pilha. Alguns possuem capacidades de armazenamento dos endereços de retorno imbuidas. Outros processadores utilizam áreas reservadas da memória externa para Pilha e limitam-se a manter actualizado num registo um ponteiro de pilha (Stack Pointer) que contem o endereço da mais recente inserção na pilha. A utilização de uma pilha externa torna ilimitada a possibilidade de imbricamento de chamadas de subrotinas.Para além disso, se o processador possuir instruções que permitam guardar na pilha (Push) e dela retirar (Pop) os conteúdos do acumulador e dos outros registos de uso geral, torna-se possível o processamento multi-nível de interrupções (Interrupts). O estado (status) do processador (isto é o conteúdo dos seus registos) pode ser guardado na pilha quando uma interrupção é atendida e reposto depois do atendimento da interrupção.

Registo de Instruções e Descodificador

Cada computador possui um comprimento de palavra que caracteriza a máquina. O comprimento de palavra de um computador é normalmente determinado pela capacidade dos seus elementos internos de armazenamento e das suas vias de transferência de dados (bus - barramento / plural - busses). Por exemplo, um computador cujos registos e barramentos possam armazenar e transferir 8 bits de cada vez, diz-se que possui um comprimento de palavra de 8 bits (processador de 8 bits). Um processador de 8 bits é adequado para tratar entidades de 8 bits (1 byte), pelo que a memória associada é também organizada em localizações de 1 byte. Quer dados quer instruções são armazenadas em memória como palavras binárias de 8 bits ou múltiplas desta (16, 24).

Cada uma das operações que o processador pode executar é associado a uma palavra de um byte que recebe o nome de Código de Operação (Instruction Code ou Operacion Code ou opcode). A utilização de palavras de 8 bits para códigos de operação, possibilita a existência de 256 instruções diferentes .

O processador executa cada instrução, por meio de duas operações distintas. Em primeiro lugar, o processador transmite à memória o endereço existente no contador de programa. A memória envia então o dado existente nessa possição. A CPU guarda esse dado de um byte num registo designado Registo de Instruções (Instruction Register).

O mecanismo que leva à descodificação do código de operação pelo processador nas acções específicas necessárias à sua execução ultrapassa o âmbito deste texto introdutório.

Os oito bits armazenados no registo de instruções pode ser descodificado e utilizado para descodificar uma das 256 linhas de saída. Cada uma destas linhas significa um conjunto de acções associado com a execução de um determinado código de operação. Esta tradução de códigos para acções é realizada pelo Descodificador de Instruções e pelos circuitos de controlo associados.

Um código de instruções de oito bits é normalmente suficiente para especificar uma acção de tratamento de dados. Por vezes, existe a necessidade de mais de oito bits para executar a acção.

Um exemplo disso é quando a instrução se refere a uma localização de memória. O código de instrução identifica a acção a ser realizada, mas não pode especificar o endereço. Neste tipo de casos, tem que ser utilizado um código de instrução de dois ou três bytes. Os bytes do código de instrução são armazenados sucessivamente em memória, e o processador executa duas ou três leituras de dados da memória sucessivas para obter a totalidade da instrução. O primeiro byte retirado da memória é colocado no registo descodificador de instruções e os bytes seguintes são temporariamente armazenados.

Registo(s) de Endereços

A CPU pode utilizar um registo ou par-de-registos para armazenar o endereço de uma posição de memória. Se o registo de endreços for Programável, isto é, se existirem instruções que permitem ao uilizadoe alterer o conteúdo dos registos, o programa pode construir um endereço no registo de endereços, antes de executar uma instrução Referida à Memória (isto é, que leia ou escreva dados em memória ou efectue a manipulação de dados em memória).

Unidade Aritmética e Lógica (ALU)

Todos os processadores possuem uma unidade aritmética e lógica, habitualmente designada por ALU. A ALU, como se deduz do nome, é a parte do hardware da CPU que executa as operações aritméticas e lógicas sobre os dados binários.

A ALU contem um Somador , capaz de combinar por adição, os conteúdos de dois registos.

Um programador experimentado pode, a partir da adição, escrever rotinas de subtracção, multiplicação ou divisão. Na prática, no entanto, as ALUs possuem outras capacidades incluídas, nomeadamente as operações lógicas booleanas.

A ALU possui Bits Flag, que especificam condições que acontecem durante as operações lógicas e aritméticas. As flags mais típicas são Transporte(Carry), Zero, Sinal e Paridade.

Podemos programar saltos que dependam das condições de uma ou mais flags.

Circuitos de Controlo 

Os circuitos de controlo são a unidade primária do CPU. O circuito de controlo, utiliza um sinal de relógio (clock) para manter a sequência definida de acções necessárias a uma tarefa. Após a leitura e descodificação de uma instrução, o circuito de controlo produz os sinais necessários à execução da acção. Normalmente o circuito de controlo é capaz de responder a sinais externos, como é o caso dos pedidos de interrupt e de espera. Um pedido de Interrupção (Interrupt) leva o circuito de controlo a interromper temporariamente a execução do programa principal, saltar para uma rotina de serviço do interrupt e regressa automaticamente ao programa principal. Um pedido de Espera (Wait) é normalmente proveniente de uma memória ou outro dispositivo de E/S que seja mais lento que a CPU. O circuito de controlo manterá a CPU parada (idle) até que a memória ou o dispositivo de E/S esteja acessível.