Quem sou eu

Minha foto
Salvador, BA, Brazil
Analista de sistemas, expert em telecom, formado em Eng. Elétrica e nerd assumido

sexta-feira, 22 de outubro de 2010

Sistemas de Computação 5 - O Ciclo Fetch-Execute

Já vimos o aspecto das instruções de máquina e seu conteúdo, mas ainda precisamos entender o processo pelo qual a CPU consegue efetivamente executar a sequência de instruções de máquina que forma o programa. Primeiro: como as instruções de máquina do programa organizam-se na memória?

Elas ficam armazenadas de forma sequencial, e sua execução também ocorre de forma sequencial, a menos que a própria instrução em execução provoque um desvio. Neste caso a sequência linear de execução das instruções é retomada a partir do endereço de memória para onde ocorreu o desvio.

Vamos, por enquanto, deixar pendente a questão de como as instruções de máquina foram colocadas na memória exatamente daquela maneira. Para a execução das instruções de máquina a CPU utiliza dois registradores de controle:
  • Program counter (PC): armazena o endereço na memória da próxima instrução a executar;
  • Instruction register (IR): armazena o código da instrução em execução.
Estes registradores são utilizados em uma sequência de ações da CPU, conhecido como ciclo fetch-execute
  1. Instruction fetch: usando o endereço contido no PC, a unidade de controle comanda a leitura da próxima instrução da memória para o IR;
  2. Instruction decode: a unidade de controle identifica o OpCode  e as referências aos operandos da instrução no IR. Após isso a unidade de controle incrementa o valor do PC com o número de bytes da instrução que está carregada no IR;
  3. Operand fetch: os conteúdos dos operandos da instrução no IR são copiados de seus locais de origem para os registradores de entrada da ALU;
  4. Execute: a unidade de controle aciona os circuitos da ALU necessários para a execução da instrução e o resultado é armazenado em um registrador de saída da ALU. Eventuais ocorrências durante a execução da instrução (ex.: overflow aritmético) são registrados em alguns bits, denominados condition code) de um dos registadores de controle;
  5. Result store: o conteúdo do registrador de saída da ALU é copiado para sua localização defnitiva;
  6. volta ao passo 1.

Isto é o essencial por enquanto. Mais tarde vamos ver que, por causa do mecanismo de interrupções, o ciclo fetch-execute das máquinas modernas é um pouquinho mais complicado. Apenas para manter o hábito, abaixo vai uma figura que representa o ciclo fetch-execute (tal como o conhecemos até agora) na forma de um fluxograma.


A partir desta descrição podemos entender os vários tipos de instrução de máquina geralmente reconhecidos pela unidade de controle da CPU (embora cada fabricante de processador faça isto de modo ligeiramente diferente, e dê diferentes nomes para coisas que fazem essencialmente a mesma coisa):
  • Instruções aritméticas: executam operações aritméticas sobre operandos que armazenam números inteiros e reais (eventualmente também sobre vetores, matrizes ou tensores de números inteiros ou reais);
  • Instruções lógicas: executam operações lógicas (AND, OR, XOR, NOT, etc.) sobre operandos que, geralmente, são tratados como se armazenassem apenas um string de bits;
  • Instruções de comparação: comparam o conteúdo dos operandos como sendo strings de bits ou como valores numéricos e, em geral, expressam o resultado da comparação (operandos iguais, 1° operando maior ou 2° operando maior) nos bits do condition code;
  • Instruções de desvio: provocam a quebra da execução sequencial das instruções na memória, forçando que ela seja retomada a partir do endereço de memória dado como operando da instrução (conhecido como jump address ou branch address). Existem dois tipos de instruções de desvio: desvio incondicional, onde o desvio para o jump address fornecido sempre ocorre, e desvio incondicional, onde o desvio para o jump address fornecido pode ocorrer ou não, a depender de mais um operando da instrução, que controla as condições de ocorrência ou não do desvio (geralmente este operando é um string de bits que, juntamente com os bits do condition code, sofrem uma operação de XOR cujo padrão de bits resultante define se ocorrerá ou não o desvio);
  • Instruções de movimentação: provocam a cópia de conteúdos da memória para os registradores, dos registradores para a memória e (quase sempre) de um local na memória para outro.
  • Instruções de controle: permitem ao programador efetuar operações sobre os registradores de controle, afetando assim o ocmportamento da CPU (ex.: instruções para permitir ou mascarar temporariamente que a CPU reconheça determinados tipos de interrupções).

As instruções de controle, bem como o acesso a determinadas áreas da memória, tem um grande potencial para provocar "travamento" da CPU caso não sejam uusadas da forma apropriada. Por isso geralmente essas instruções (e a manipulação das áreas restritas da memória) são consideradas instruções privilegiadas, e a CPU só admite a sua execução se o programa for habilitado para isso.

Aqui nós temos um aparente paradoxo: colocar a CPU em modo de aceitar a execução de instruções privilegiadas só pode ser feito pela execução de instruções privilegiadas. Como pode ser isso? Peço que vocês tenham um pouco de fé, por enquanto. Quando chegarmos aos tópicos sobre sistemas operacionais isto vai ficar mais claro.

No próximo artigo vamos falar de algumas coisinhas para melhorar a performance do ciclo fetch-execute básico.

Um comentário:

  1. Grande Mestre. Também me considero um dos integrantes da caterva e vou a luta todo dia e a toda hora. Sua chegada a Hispaniola mostra mais um descobridor dos sete mares deitando falação a ser escutada e deglutida, da mesma forma que os Caetés fizeram com o Bispo Sardinha. Um abração.

    ResponderExcluir